feat(auth): support schema-qualified SQL stores
This commit is contained in:
1 parent
a85cbf240d
commit
681679483a
5 files changed
+48
-4
No files matched your search
@@ -8,6 +8,7 @@ export {
|
||||
export type { AuthStore } from "./store.ts";
|
||||
export { MemoryAuthStore } from "./stores/memory.ts";
|
||||
export { SqlAuthStore } from "./stores/sql.ts";
|
||||
export type { SqlAuthStoreOptions } from "./stores/sql.ts";
|
||||
export {
|
||||
authSession,
|
||||
requireAuth,
|
||||
|
||||
@@ -34,10 +34,31 @@ function placeholders(sql: string, dialect: string): string {
|
||||
return sql.replace(/\?/g, () => `$${++index}`);
|
||||
}
|
||||
|
||||
export interface SqlAuthStoreOptions {
|
||||
/** PostgreSQL schema owning authentication tables. */
|
||||
schema?: string;
|
||||
/** Defaults to wrn_auth_; use an empty prefix for e.g. sso.users. */
|
||||
tablePrefix?: string;
|
||||
}
|
||||
|
||||
export class SqlAuthStore implements AuthStore {
|
||||
constructor(private readonly db: Db) {}
|
||||
constructor(
|
||||
private readonly db: Db,
|
||||
private readonly options: SqlAuthStoreOptions = {},
|
||||
) {
|
||||
if (options.schema && !/^[a-z_][a-z0-9_]*$/i.test(options.schema))
|
||||
throw new Error("Invalid auth schema identifier");
|
||||
if (options.tablePrefix && !/^[a-z_][a-z0-9_]*$/i.test(options.tablePrefix))
|
||||
throw new Error("Invalid auth table prefix");
|
||||
if (options.schema && db.driver.dialect !== "postgres")
|
||||
throw new Error("Auth schema requires PostgreSQL");
|
||||
}
|
||||
private sql(value: string): string {
|
||||
return placeholders(value, this.db.driver.dialect);
|
||||
const qualified = value.replace(/\bwrn_auth_([a-z_]+)\b/g, (_match, table: string) => {
|
||||
const name = (this.options.tablePrefix ?? "wrn_auth_") + table;
|
||||
return this.options.schema ? '"' + this.options.schema + '"."' + name + '"' : name;
|
||||
});
|
||||
return placeholders(qualified, this.db.driver.dialect);
|
||||
}
|
||||
private async one(sql: string, params: unknown[] = []): Promise<Row | undefined> {
|
||||
return (await this.db.one(this.sql(sql), params)) ?? undefined;
|
||||
|
||||
Reference in new issue
Block a user