added cookie to config + fixed config set endpoint

This commit is contained in:
dswbx
2024-11-25 16:57:12 +01:00
parent 824ff40133
commit 16a6a3315d
14 changed files with 114 additions and 47 deletions

View File

@@ -63,7 +63,8 @@ export class AppAuth extends Module<typeof authConfigSchema> {
});
this._authenticator = new Authenticator(strategies, this.resolveUser.bind(this), {
jwt: this.config.jwt
jwt: this.config.jwt,
cookie: this.config.cookie
});
this.registerEntities();
@@ -115,6 +116,9 @@ export class AppAuth extends Module<typeof authConfigSchema> {
identifier,
profile
});
if (!this.config.allow_register && action === "register") {
throw new Exception("Registration is not allowed", 403);
}
const fields = this.getUsersEntity()
.getFillableFields("create")

View File

@@ -1,4 +1,4 @@
import { jwtConfig } from "auth/authenticate/Authenticator";
import { cookieConfig, jwtConfig } from "auth/authenticate/Authenticator";
import { CustomOAuthStrategy, OAuthStrategy, PasswordStrategy } from "auth/authenticate/strategies";
import { type Static, StringRecord, Type, objectTransform } from "core/utils";
@@ -51,7 +51,9 @@ export const authConfigSchema = Type.Object(
enabled: Type.Boolean({ default: false }),
basepath: Type.String({ default: "/api/auth" }),
entity_name: Type.String({ default: "users" }),
allow_register: Type.Optional(Type.Boolean({ default: true })),
jwt: jwtConfig,
cookie: cookieConfig,
strategies: Type.Optional(
StringRecord(strategiesSchema, {
title: "Strategies",

View File

@@ -1,8 +1,17 @@
import { Exception } from "core";
import { addFlashMessage } from "core/server/flash";
import { type Static, type TSchema, Type, parse, randomString, transformObject } from "core/utils";
import {
type Static,
StringEnum,
type TSchema,
Type,
parse,
randomString,
transformObject
} from "core/utils";
import type { Context, Hono } from "hono";
import { deleteCookie, getSignedCookie, setSignedCookie } from "hono/cookie";
import type { CookieOptions } from "hono/utils/cookie";
import { type JWTVerifyOptions, SignJWT, jwtVerify } from "jose";
type Input = any; // workaround
@@ -41,6 +50,18 @@ export interface UserPool<Fields = "id" | "email" | "username"> {
create: (user: CreateUser) => Promise<User | undefined>;
}
export const cookieConfig = Type.Partial(
Type.Object({
renew: Type.Boolean({ default: true }),
path: Type.String({ default: "/" }),
sameSite: StringEnum(["strict", "lax", "none"], { default: "lax" }),
secure: Type.Boolean({ default: true }),
httpOnly: Type.Boolean({ default: true }),
expires: Type.Number({ default: 168 })
}),
{ default: {}, additionalProperties: false }
);
export const jwtConfig = Type.Object(
{
// @todo: autogenerate a secret if not present. But it must be persisted from AppAuth
@@ -56,7 +77,8 @@ export const jwtConfig = Type.Object(
}
);
export const authenticatorConfig = Type.Object({
jwt: jwtConfig
jwt: jwtConfig,
cookie: cookieConfig
});
type AuthConfig = Static<typeof authenticatorConfig>;
@@ -179,12 +201,12 @@ export class Authenticator<Strategies extends Record<string, Strategy> = Record<
return false;
}
// @todo: CookieOptions not exported from hono
private get cookieOptions(): any {
private get cookieOptions(): CookieOptions {
const { expires = 168, renew, ...cookieConfig } = this.config.cookie;
return {
path: "/",
sameSite: "lax",
httpOnly: true
...cookieConfig,
expires: new Date(Date.now() + expires * 60 * 60 * 1000)
};
}
@@ -200,6 +222,16 @@ export class Authenticator<Strategies extends Record<string, Strategy> = Record<
return token;
}
async requestCookieRefresh(c: Context) {
if (this.config.cookie.renew) {
console.log("renewing cookie", c.req.url);
const token = await this.getAuthCookie(c);
if (token) {
await this.setAuthCookie(c, token);
}
}
}
private async setAuthCookie(c: Context, token: string) {
const secret = this.config.jwt.secret;
await setSignedCookie(c, "auth", token, secret, this.cookieOptions);