diff --git a/app/src/auth/authenticate/Authenticator.ts b/app/src/auth/authenticate/Authenticator.ts index 19088d90..13fa6bc0 100644 --- a/app/src/auth/authenticate/Authenticator.ts +++ b/app/src/auth/authenticate/Authenticator.ts @@ -299,8 +299,8 @@ export class Authenticator = Record< } } - private getSuccessPath(c: Context) { - const p = (this.config.cookie.pathSuccess ?? "/").replace(/\/+$/, "/"); + private getSafeUrl(c: Context, path: string) { + const p = path.replace(/\/+$/, "/"); // nextjs doesn't support non-fq urls // but env could be proxied (stackblitz), so we shouldn't fq every url @@ -316,7 +316,7 @@ export class Authenticator = Record< return c.json(data); } - const successUrl = this.getSuccessPath(c); + const successUrl = this.getSafeUrl(c, redirect ?? this.config.cookie.pathSuccess ?? "/"); const referer = redirect ?? c.req.header("Referer") ?? successUrl; //console.log("auth respond", { redirect, successUrl, successPath }); diff --git a/app/src/auth/authenticate/strategies/PasswordStrategy.ts b/app/src/auth/authenticate/strategies/PasswordStrategy.ts index d8f8a23e..c6a9a376 100644 --- a/app/src/auth/authenticate/strategies/PasswordStrategy.ts +++ b/app/src/auth/authenticate/strategies/PasswordStrategy.ts @@ -1,4 +1,5 @@ import type { Authenticator, Strategy } from "auth"; +import { isDebug, tbValidator as tb } from "core"; import { type Static, StringEnum, Type, parse } from "core/utils"; import { hash } from "core/utils"; import { type Context, Hono } from "hono"; @@ -56,26 +57,56 @@ export class PasswordStrategy implements Strategy { const hono = new Hono(); return hono - .post("/login", async (c) => { - const body = await authenticator.getBody(c); - - try { - const payload = await this.login(body); - const data = await authenticator.resolve("login", this, payload.password, payload); - - return await authenticator.respond(c, data); - } catch (e) { - return await authenticator.respond(c, e); + .post( + "/login", + tb( + "query", + Type.Object({ + redirect: Type.Optional(Type.String()) + }) + ), + async (c) => { + const body = await authenticator.getBody(c); + const { redirect } = c.req.valid("query"); + + try { + const payload = await this.login(body); + const data = await authenticator.resolve( + "login", + this, + payload.password, + payload + ); + + return await authenticator.respond(c, data, redirect); + } catch (e) { + return await authenticator.respond(c, e); + } } - }) - .post("/register", async (c) => { - const body = await authenticator.getBody(c); - - const payload = await this.register(body); - const data = await authenticator.resolve("register", this, payload.password, payload); - - return await authenticator.respond(c, data); - }); + ) + .post( + "/register", + tb( + "query", + Type.Object({ + redirect: Type.Optional(Type.String()) + }) + ), + async (c) => { + const body = await authenticator.getBody(c); + const { redirect } = c.req.valid("query"); + + const payload = await this.register(body); + const data = await authenticator.resolve( + "register", + this, + payload.password, + payload + ); + + return await authenticator.respond(c, data, redirect); + } + ); } getActions(): StrategyActions {