File tree Expand file tree Collapse file tree 4 files changed +28
-3
lines changed Expand file tree Collapse file tree 4 files changed +28
-3
lines changed Original file line number Diff line number Diff line change @@ -33,13 +33,17 @@ class HttpToolkitServer extends Command {
33
33
version : flags . version ( { char : 'v' } ) ,
34
34
help : flags . help ( { char : 'h' } ) ,
35
35
36
- config : flags . string ( { char : 'c' , description : 'path in which to store config files' } ) ,
36
+ config : flags . string ( { char : 'c' , description : 'optional path in which to store config files' } ) ,
37
+ token : flags . string ( { char : 't' , description : 'optional token to authenticate local server access' } ) ,
37
38
}
38
39
39
40
async run ( ) {
40
41
const { flags } = this . parse ( HttpToolkitServer ) ;
41
42
42
- await runHTK ( { configPath : flags . config } ) . catch ( async ( error ) => {
43
+ await runHTK ( {
44
+ configPath : flags . config ,
45
+ authToken : flags . token
46
+ } ) . catch ( async ( error ) => {
43
47
await reportError ( error ) ;
44
48
throw error ;
45
49
} ) ;
Original file line number Diff line number Diff line change 1
1
export interface HtkConfig {
2
2
configPath : string ;
3
+ authToken ?: string ;
3
4
https : {
4
5
keyPath : string ;
5
6
certPath : string ;
Original file line number Diff line number Diff line change @@ -5,6 +5,7 @@ import corsGate = require('cors-gate');
5
5
import { GraphQLServer } from 'graphql-yoga' ;
6
6
import { GraphQLScalarType } from 'graphql' ;
7
7
import { generateSPKIFingerprint } from 'mockttp' ;
8
+ import { Request , Response } from 'express' ;
8
9
9
10
import { HtkConfig } from './config' ;
10
11
import { reportError , addBreadcrumb } from './error-tracking' ;
@@ -184,6 +185,23 @@ export class HttpToolkitServer extends events.EventEmitter {
184
185
allowSafe : false , // Even for HEAD/GET requests (should be none anyway)
185
186
origin : '' // No origin - we accept *no* same-origin requests
186
187
} ) ) ;
188
+
189
+ if ( config . authToken ) {
190
+ // Optional auth token. This allows us to lock down UI/server communication further
191
+ // when started together. The desktop generates a token every run and passes it to both.
192
+ this . graphql . use ( ( req : Request , res : Response , next : ( ) => void ) => {
193
+ const authHeader = req . headers [ 'authorization' ] || '' ;
194
+
195
+ const tokenMatch = authHeader . match ( / B e a r e r ( \S + ) / ) || [ ] ;
196
+ const token = tokenMatch [ 1 ] ;
197
+
198
+ if ( token !== config . authToken ) {
199
+ res . status ( 403 ) . send ( 'Valid token required' ) ;
200
+ } else {
201
+ next ( ) ;
202
+ }
203
+ } ) ;
204
+ }
187
205
}
188
206
189
207
async start ( ) {
Original file line number Diff line number Diff line change @@ -66,6 +66,7 @@ function checkCertExpiry(contents: string): void {
66
66
67
67
export async function runHTK ( options : {
68
68
configPath ?: string
69
+ authToken ?: string
69
70
} = { } ) {
70
71
const startTime = Date . now ( ) ;
71
72
registerShutdownHandler ( ) ;
@@ -83,7 +84,7 @@ export async function runHTK(options: {
83
84
const certSetupTime = Date . now ( ) ;
84
85
console . log ( 'Certificates setup in' , certSetupTime - configCheckTime , 'ms' ) ;
85
86
86
- // Start a standalone server
87
+ // Start a Mockttp standalone server
87
88
const standalone = getStandalone ( {
88
89
serverDefaults : {
89
90
cors : false ,
@@ -103,6 +104,7 @@ export async function runHTK(options: {
103
104
// Start a HTK server
104
105
const htkServer = new HttpToolkitServer ( {
105
106
configPath,
107
+ authToken : options . authToken ,
106
108
https : httpsConfig
107
109
} ) ;
108
110
You can’t perform that action at this time.
0 commit comments