Archived
1
0

refactor: make authenticated async everywhere

Since this checks if they are authenticated using the hash/password and it's
async, we need to update authenticated to be async, which means we have to
update it everywhere it's used.
This commit is contained in:
Joe Previte 2021-06-02 13:21:59 -07:00
parent fcc3f0d951
commit 0cdbd33b46
No known key found for this signature in database
GPG Key ID: 2C91590C6B742C24
5 changed files with 20 additions and 10 deletions

View File

@ -45,8 +45,13 @@ export const replaceTemplates = <T extends object>(
/** /**
* Throw an error if not authorized. Call `next` if provided. * Throw an error if not authorized. Call `next` if provided.
*/ */
export const ensureAuthenticated = (req: express.Request, _?: express.Response, next?: express.NextFunction): void => { export const ensureAuthenticated = async (
if (!authenticated(req)) { req: express.Request,
_?: express.Response,
next?: express.NextFunction,
): Promise<void> => {
const isAuthenticated = await authenticated(req)
if (!isAuthenticated) {
throw new HttpError("Unauthorized", HttpCode.Unauthorized) throw new HttpError("Unauthorized", HttpCode.Unauthorized)
} }
if (next) { if (next) {
@ -57,17 +62,19 @@ export const ensureAuthenticated = (req: express.Request, _?: express.Response,
/** /**
* Return true if authenticated via cookies. * Return true if authenticated via cookies.
*/ */
export const authenticated = (req: express.Request): boolean => { export const authenticated = async (req: express.Request): Promise<boolean> => {
switch (req.args.auth) { switch (req.args.auth) {
case AuthType.None: case AuthType.None:
return true return true
case AuthType.Password: case AuthType.Password:
// The password is stored in the cookie after being hashed. // The password is stored in the cookie after being hashed.
// TODO@jsjoeio this also needs to be refactored to check if they're using the legacy password
// or the new one. we can't assume hashed-password means legacy
return !!( return !!(
req.cookies.key && req.cookies.key &&
(req.args["hashed-password"] (req.args["hashed-password"]
? safeCompare(req.cookies.key, req.args["hashed-password"]) ? safeCompare(req.cookies.key, req.args["hashed-password"])
: req.args.password && isHashMatch(req.args.password, req.cookies.key)) : req.args.password && (await isHashMatch(req.args.password, req.cookies.key)))
) )
default: default:
throw new Error(`Unsupported auth type ${req.args.auth}`) throw new Error(`Unsupported auth type ${req.args.auth}`)

View File

@ -32,14 +32,15 @@ const maybeProxy = (req: Request): string | undefined => {
return port return port
} }
router.all("*", (req, res, next) => { router.all("*", async (req, res, next) => {
const port = maybeProxy(req) const port = maybeProxy(req)
if (!port) { if (!port) {
return next() return next()
} }
// Must be authenticated to use the proxy. // Must be authenticated to use the proxy.
if (!authenticated(req)) { const isAuthenticated = await authenticated(req)
if (!isAuthenticated) {
// Let the assets through since they're used on the login page. // Let the assets through since they're used on the login page.
if (req.path.startsWith("/static/") && req.method === "GET") { if (req.path.startsWith("/static/") && req.method === "GET") {
return next() return next()

View File

@ -49,9 +49,9 @@ const limiter = new RateLimiter()
export const router = Router() export const router = Router()
router.use((req, res, next) => { router.use(async (req, res, next) => {
const to = (typeof req.query.to === "string" && req.query.to) || "/" const to = (typeof req.query.to === "string" && req.query.to) || "/"
if (authenticated(req)) { if (await authenticated(req)) {
return redirect(req, res, to, { to: undefined }) return redirect(req, res, to, { to: undefined })
} }
next() next()

View File

@ -43,7 +43,8 @@ router.get("/(:commit)(/*)?", async (req, res) => {
// Make sure it's in code-server if you aren't authenticated. This lets // Make sure it's in code-server if you aren't authenticated. This lets
// unauthenticated users load the login assets. // unauthenticated users load the login assets.
if (!resourcePath.startsWith(rootPath) && !authenticated(req)) { const isAuthenticated = await authenticated(req)
if (!resourcePath.startsWith(rootPath) && !isAuthenticated) {
throw new HttpError("Unauthorized", HttpCode.Unauthorized) throw new HttpError("Unauthorized", HttpCode.Unauthorized)
} }

View File

@ -19,7 +19,8 @@ export const router = Router()
const vscode = new VscodeProvider() const vscode = new VscodeProvider()
router.get("/", async (req, res) => { router.get("/", async (req, res) => {
if (!authenticated(req)) { const isAuthenticated = await authenticated(req)
if (!isAuthenticated) {
return redirect(req, res, "login", { return redirect(req, res, "login", {
// req.baseUrl can be blank if already at the root. // req.baseUrl can be blank if already at the root.
to: req.baseUrl && req.baseUrl !== "/" ? req.baseUrl : undefined, to: req.baseUrl && req.baseUrl !== "/" ? req.baseUrl : undefined,