Fix: OneTimeLinks (#1719)

* fix otls

* one otl per client

* revert some code

* revert some more code, add comments

* adjust migration
This commit is contained in:
Bernd Storath
2025-03-07 09:16:24 +01:00
committed by GitHub
parent fcb5049dab
commit e5fb6ff3a6
11 changed files with 57 additions and 51 deletions
@@ -42,7 +42,7 @@ export const client = sqliteTable('clients_table', {
export const clientsRelations = relations(client, ({ one }) => ({
oneTimeLink: one(oneTimeLink, {
fields: [client.id],
references: [oneTimeLink.clientId],
references: [oneTimeLink.id],
}),
user: one(user, {
fields: [client.userId],
@@ -4,6 +4,7 @@ import { sqliteTable, text } from 'drizzle-orm/sqlite-core';
import { wgInterface } from '../../schema';
export const hooks = sqliteTable('hooks_table', {
/** same as `wgInterface.name` */
id: text()
.primaryKey()
.references(() => wgInterface.name, {
@@ -4,12 +4,15 @@ import { int, sqliteTable, text } from 'drizzle-orm/sqlite-core';
import { client } from '../../schema';
export const oneTimeLink = sqliteTable('one_time_links_table', {
id: int().primaryKey({ autoIncrement: true }),
/** same as `client.id` */
id: int()
.primaryKey()
.references(() => client.id, {
onDelete: 'cascade',
onUpdate: 'cascade',
}),
oneTimeLink: text('one_time_link').notNull().unique(),
expiresAt: text('expires_at').notNull(),
clientId: int('client_id')
.notNull()
.references(() => client.id, { onDelete: 'cascade', onUpdate: 'cascade' }),
createdAt: text('created_at')
.notNull()
.default(sql`(CURRENT_TIMESTAMP)`),
@@ -21,7 +24,7 @@ export const oneTimeLink = sqliteTable('one_time_links_table', {
export const oneTimeLinksRelations = relations(oneTimeLink, ({ one }) => ({
client: one(client, {
fields: [oneTimeLink.clientId],
fields: [oneTimeLink.id],
references: [client.id],
}),
}));
@@ -12,7 +12,7 @@ function createPreparedStatement(db: DBType) {
create: db
.insert(oneTimeLink)
.values({
clientId: sql.placeholder('id'),
id: sql.placeholder('id'),
oneTimeLink: sql.placeholder('oneTimeLink'),
expiresAt: sql.placeholder('expiresAt'),
})
@@ -20,7 +20,12 @@ function createPreparedStatement(db: DBType) {
erase: db
.update(oneTimeLink)
.set({ expiresAt: sql.placeholder('expiresAt') as never as string })
.where(eq(oneTimeLink.clientId, sql.placeholder('id')))
.where(eq(oneTimeLink.id, sql.placeholder('id')))
.prepare(),
findByOneTimeLink: db.query.oneTimeLink
.findFirst({
where: eq(oneTimeLink.oneTimeLink, sql.placeholder('oneTimeLink')),
})
.prepare(),
};
}
@@ -36,6 +41,10 @@ export class OneTimeLinkService {
return this.#statements.delete.execute({ id });
}
getByOtl(oneTimeLink: string) {
return this.#statements.findByOneTimeLink.execute({ oneTimeLink });
}
generate(id: ID) {
const key = `${id}-${Math.floor(Math.random() * 1000)}`;
const oneTimeLink = Math.abs(CRC32.str(key)).toString(16);
@@ -45,7 +54,7 @@ export class OneTimeLinkService {
}
erase(id: ID) {
const expiresAt = Date.now() + 10 * 1000;
const expiresAt = new Date(Date.now() + 10 * 1000).toISOString();
return this.#statements.erase.execute({ id, expiresAt });
}
}
@@ -5,6 +5,7 @@ import { wgInterface } from '../../schema';
// default* means clients store it themselves
export const userConfig = sqliteTable('user_configs_table', {
/** same as `wgInterface.name` */
id: text()
.primaryKey()
.references(() => wgInterface.name, {