Commit | Line | Data |
---|---|---|
66a7748d | 1 | import type { IncomingMessage } from 'node:http' |
8114d10e | 2 | |
75adc3d8 | 3 | import { BaseError } from '../../exception/index.js' |
66a7748d | 4 | import { Protocol, ProtocolVersion } from '../../types/index.js' |
4c3f6c20 | 5 | import { logger, logPrefix } from '../../utils/index.js' |
4198ad5c | 6 | |
75adc3d8 JB |
7 | export const getUsernameAndPasswordFromAuthorizationToken = ( |
8 | authorizationToken: string, | |
9 | next: (err?: Error) => void | |
10 | ): [string, string] => { | |
11 | if ( | |
12 | !/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/.test(authorizationToken) | |
13 | ) { | |
14 | next(new BaseError('Invalid basic authentication token format')) | |
d5bd1c00 | 15 | } |
75adc3d8 JB |
16 | const authentication = Buffer.from(authorizationToken, 'base64').toString() |
17 | const authenticationParts = authentication.split(/:/) | |
18 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion | |
19 | return [authenticationParts.shift()!, authenticationParts.join(':')] | |
20 | } | |
d5bd1c00 | 21 | |
75adc3d8 JB |
22 | export const handleProtocols = ( |
23 | protocols: Set<string>, | |
24 | _request: IncomingMessage | |
25 | ): string | false => { | |
26 | let protocol: Protocol | undefined | |
27 | let version: ProtocolVersion | undefined | |
28 | if (protocols.size === 0) { | |
66a7748d JB |
29 | return false |
30 | } | |
75adc3d8 JB |
31 | for (const fullProtocol of protocols) { |
32 | if (isProtocolAndVersionSupported(fullProtocol)) { | |
33 | return fullProtocol | |
34 | } | |
66a7748d | 35 | } |
75adc3d8 JB |
36 | logger.error( |
37 | `${logPrefix( | |
38 | ' UI WebSocket Server |' | |
39 | )} Unsupported protocol: '${protocol}' or protocol version: '${version}'` | |
40 | ) | |
41 | return false | |
42 | } | |
1f7fa4de | 43 | |
75adc3d8 JB |
44 | export const isProtocolAndVersionSupported = (protocolStr: string): boolean => { |
45 | const [protocol, version] = getProtocolAndVersion(protocolStr) | |
46 | return ( | |
47 | Object.values(Protocol).includes(protocol) && Object.values(ProtocolVersion).includes(version) | |
48 | ) | |
49 | } | |
a92929f1 | 50 | |
75adc3d8 JB |
51 | export const getProtocolAndVersion = (protocolStr: string): [Protocol, ProtocolVersion] => { |
52 | const protocolIndex = protocolStr.indexOf(Protocol.UI) | |
53 | const protocol = protocolStr.substring( | |
54 | protocolIndex, | |
55 | protocolIndex + Protocol.UI.length | |
56 | ) as Protocol | |
57 | const version = protocolStr.substring(protocolIndex + Protocol.UI.length) as ProtocolVersion | |
58 | return [protocol, version] | |
59 | } | |
60 | ||
61 | export const isLoopback = (address: string): boolean => { | |
62 | // eslint-disable-next-line no-useless-escape | |
63 | return /^localhost$|^127(?:\.\d+){0,2}\.\d+$|^(?:0*\:)*?:?0*1$/i.test(address) | |
4198ad5c | 64 | } |