Refactor and move things a bit

This commit is contained in:
Sergio Padrino 2021-01-29 12:13:48 +01:00
parent 744c25a5a0
commit e833f9c525
4 changed files with 118 additions and 113 deletions

View file

@ -1,6 +1,6 @@
import { getKeyForEndpoint } from '../auth'
import { TokenStore } from '../stores'
import { TrampolineCommandHandler } from './trampoline-server'
import { TrampolineCommandHandler } from './trampoline-command'
export const askpassTrampolineHandler: TrampolineCommandHandler = async command => {
if (command.parameters.length !== 2) {

View file

@ -0,0 +1,103 @@
import { ITrampolineCommand } from './trampoline-command'
enum TrampolineCommandParserState {
ParameterCount,
Parameters,
EnvironmentVariablesCount,
EnvironmentVariables,
Finished,
}
export class TrampolineCommandParser {
private parameterCount: number = 0
private readonly parameters: string[] = []
private environmentVariablesCount: number = 0
private readonly environmentVariables = new Map<string, string>()
private state: TrampolineCommandParserState =
TrampolineCommandParserState.ParameterCount
public hasFinished() {
return this.state === TrampolineCommandParserState.Finished
}
public processValue(value: string) {
switch (this.state) {
case TrampolineCommandParserState.ParameterCount:
this.parameterCount = parseInt(value)
if (this.parameterCount > 0) {
this.state = TrampolineCommandParserState.Parameters
} else {
this.state = TrampolineCommandParserState.EnvironmentVariablesCount
}
break
case TrampolineCommandParserState.Parameters:
this.parameters.push(value)
if (this.parameters.length === this.parameterCount) {
this.state = TrampolineCommandParserState.EnvironmentVariablesCount
}
break
case TrampolineCommandParserState.EnvironmentVariablesCount:
this.environmentVariablesCount = parseInt(value)
if (this.environmentVariablesCount > 0) {
this.state = TrampolineCommandParserState.EnvironmentVariables
} else {
this.state = TrampolineCommandParserState.Finished
}
break
case TrampolineCommandParserState.EnvironmentVariables:
// Split after the first '='
const match = /([^=]+)=(.*)/.exec(value)
if (
match === null ||
// Length must be 3: the 2 groups + the whole string
match.length !== 3
) {
throw new Error(`Unexpected environment variable format: ${value}`)
}
const variableKey = match[1]
const variableValue = match[2]
this.environmentVariables.set(variableKey, variableValue)
if (this.environmentVariables.size === this.environmentVariablesCount) {
this.state = TrampolineCommandParserState.Finished
}
break
default:
throw new Error(`Received value during invalid state: ${this.state}`)
}
}
public toCommand(): ITrampolineCommand {
if (this.hasFinished() === false) {
throw new Error(
'The command cannot be generated if parsing is not finished'
)
}
const identifier = this.environmentVariables.get(
'DESKTOP_TRAMPOLINE_IDENTIFIER'
)
if (identifier === undefined) {
throw new Error('The command identifier is missing')
}
return {
identifier,
parameters: this.parameters,
environmentVariables: this.environmentVariables,
}
}
}

View file

@ -0,0 +1,9 @@
export interface ITrampolineCommand {
readonly identifier: string
readonly parameters: ReadonlyArray<string>
readonly environmentVariables: ReadonlyMap<string, string>
}
export type TrampolineCommandHandler = (
command: ITrampolineCommand
) => Promise<string | undefined>

View file

@ -1,120 +1,13 @@
import { createServer, AddressInfo, Server, Socket } from 'net'
import split2 from 'split2'
import { enableDesktopTrampoline } from '../feature-flag'
import {
ITrampolineCommand,
TrampolineCommandHandler,
} from './trampoline-command'
import { TrampolineCommandParser } from './trampoline-command-parser'
import { isValidTrampolineToken } from './trampoline-tokens'
interface ITrampolineCommand {
readonly identifier: string
readonly parameters: ReadonlyArray<string>
readonly environmentVariables: ReadonlyMap<string, string>
}
enum TrampolineCommandParserState {
ParameterCount,
Parameters,
EnvironmentVariablesCount,
EnvironmentVariables,
Finished,
}
class TrampolineCommandParser {
private parameterCount: number = 0
private readonly parameters: string[] = []
private environmentVariablesCount: number = 0
private readonly environmentVariables = new Map<string, string>()
private state: TrampolineCommandParserState =
TrampolineCommandParserState.ParameterCount
public hasFinished() {
return this.state === TrampolineCommandParserState.Finished
}
public processValue(value: string) {
switch (this.state) {
case TrampolineCommandParserState.ParameterCount:
this.parameterCount = parseInt(value)
if (this.parameterCount > 0) {
this.state = TrampolineCommandParserState.Parameters
} else {
this.state = TrampolineCommandParserState.EnvironmentVariablesCount
}
break
case TrampolineCommandParserState.Parameters:
this.parameters.push(value)
if (this.parameters.length === this.parameterCount) {
this.state = TrampolineCommandParserState.EnvironmentVariablesCount
}
break
case TrampolineCommandParserState.EnvironmentVariablesCount:
this.environmentVariablesCount = parseInt(value)
if (this.environmentVariablesCount > 0) {
this.state = TrampolineCommandParserState.EnvironmentVariables
} else {
this.state = TrampolineCommandParserState.Finished
}
break
case TrampolineCommandParserState.EnvironmentVariables:
// Split after the first '='
const match = /([^=]+)=(.*)/.exec(value)
if (
match === null ||
// Length must be 3: the 2 groups + the whole string
match.length !== 3
) {
throw new Error(`Unexpected environment variable format: ${value}`)
}
const variableKey = match[1]
const variableValue = match[2]
this.environmentVariables.set(variableKey, variableValue)
if (this.environmentVariables.size === this.environmentVariablesCount) {
this.state = TrampolineCommandParserState.Finished
}
break
default:
throw new Error(`Received value during invalid state: ${this.state}`)
}
}
public toCommand(): ITrampolineCommand {
if (this.hasFinished() === false) {
throw new Error(
'The command cannot be generated if parsing is not finished'
)
}
const identifier = this.environmentVariables.get(
'DESKTOP_TRAMPOLINE_IDENTIFIER'
)
if (identifier === undefined) {
throw new Error('The command identifier is missing')
}
return {
identifier,
parameters: this.parameters,
environmentVariables: this.environmentVariables,
}
}
}
export type TrampolineCommandHandler = (
command: ITrampolineCommand
) => Promise<string | undefined>
export class TrampolineServer {
private readonly server: Server
private listeningPromise: Promise<void> | null = null