@@ -4,6 +4,7 @@ import * as expressCore from "express-serve-static-core"
44import * as http from "http"
55import * as net from "net"
66import * as qs from "qs"
7+ import safeCompare from "safe-compare"
78import { Disposable } from "../common/emitter"
89import { CookieKeys , HttpCode , HttpError } from "../common/http"
910import { normalize } from "../common/util"
@@ -20,6 +21,7 @@ import {
2021 escapeHtml ,
2122 escapeJSON ,
2223 splitOnFirstEquals ,
24+ isHashMatch ,
2325} from "./util"
2426
2527/**
@@ -114,21 +116,31 @@ export const ensureAuthenticated = async (
114116/**
115117 * Validate basic auth credentials.
116118 */
117- const validateBasicAuth = ( authHeader : string | undefined , authUser : string | undefined , authPassword : string | undefined ) : boolean => {
118- if ( ! authHeader ?. startsWith ( 'Basic ' ) ) {
119- return false ;
119+ const validateBasicAuth = async (
120+ authHeader : string | undefined ,
121+ authUser : string | undefined ,
122+ authPassword : string | undefined ,
123+ hashedPassword : string | undefined ,
124+ ) : Promise < boolean > => {
125+ if ( ! authHeader ?. startsWith ( "Basic " ) ) {
126+ return false
120127 }
121128
122129 try {
123- const base64Credentials = authHeader . split ( ' ' ) [ 1 ] ;
124- const credentials = Buffer . from ( base64Credentials , 'base64' ) . toString ( 'utf-8' ) ;
125- const [ username , password ] = credentials . split ( ':' ) ;
126- return username === authUser && password === authPassword ;
130+ const base64Credentials = authHeader . split ( " " ) [ 1 ]
131+ const credentials = Buffer . from ( base64Credentials , "base64" ) . toString ( "utf-8" )
132+ const [ username , password ] = credentials . split ( ":" )
133+ if ( username !== authUser ) return false
134+ if ( hashedPassword ) {
135+ return await isHashMatch ( password , hashedPassword )
136+ } else {
137+ return safeCompare ( password , authPassword || "" )
138+ }
127139 } catch ( error ) {
128- logger . error ( ' Error validating basic auth:' + error ) ;
129- return false ;
140+ logger . error ( " Error validating basic auth:" + error )
141+ return false
130142 }
131- } ;
143+ }
132144
133145/**
134146 * Return true if authenticated via cookies.
@@ -152,7 +164,12 @@ export const authenticated = async (req: express.Request): Promise<boolean> => {
152164 return await isCookieValid ( isCookieValidArgs )
153165 }
154166 case AuthType . HttpBasic : {
155- return validateBasicAuth ( req . headers . authorization , req . args [ "auth-user" ] , req . args . password ) ;
167+ return await validateBasicAuth (
168+ req . headers . authorization ,
169+ req . args [ "auth-user" ] ,
170+ req . args . password ,
171+ req . args [ "hashed-password" ] ,
172+ )
156173 }
157174 default : {
158175 throw new Error ( `Unsupported auth type ${ req . args . auth } ` )
0 commit comments