release: WRNexusJS 0.4.0
This commit is contained in:
@@ -1,8 +1,4 @@
|
||||
import type {
|
||||
CaptchaChallengeRecord,
|
||||
CaptchaResponseTokenRecord,
|
||||
CaptchaStore,
|
||||
} from "../types.ts";
|
||||
import type { CaptchaChallengeRecord, CaptchaResponseTokenRecord, CaptchaStore } from "../types.ts";
|
||||
|
||||
export interface SqliteStatementLike {
|
||||
run(...params: unknown[]): unknown;
|
||||
@@ -21,16 +17,21 @@ export interface SqliteCaptchaStoreOptions {
|
||||
}
|
||||
|
||||
function safeIdentifier(value: string): string {
|
||||
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value)) throw new TypeError(`Unsafe SQL identifier: ${value}`);
|
||||
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value))
|
||||
throw new TypeError(`Unsafe SQL identifier: ${value}`);
|
||||
return value;
|
||||
}
|
||||
|
||||
function parseChallenge(row: Record<string, unknown> | undefined): CaptchaChallengeRecord | undefined {
|
||||
function parseChallenge(
|
||||
row: Record<string, unknown> | undefined,
|
||||
): CaptchaChallengeRecord | undefined {
|
||||
if (!row) return undefined;
|
||||
return JSON.parse(String(row.payload)) as CaptchaChallengeRecord;
|
||||
}
|
||||
|
||||
function parseToken(row: Record<string, unknown> | undefined): CaptchaResponseTokenRecord | undefined {
|
||||
function parseToken(
|
||||
row: Record<string, unknown> | undefined,
|
||||
): CaptchaResponseTokenRecord | undefined {
|
||||
if (!row) return undefined;
|
||||
return JSON.parse(String(row.payload)) as CaptchaResponseTokenRecord;
|
||||
}
|
||||
@@ -77,7 +78,13 @@ export class SqliteCaptchaStore implements CaptchaStore {
|
||||
(id, payload, expires_at, consumed_at, attempts)
|
||||
VALUES (?, ?, ?, ?, ?)`,
|
||||
)
|
||||
.run(record.id, JSON.stringify(record), record.expiresAt, record.consumedAt ?? null, record.attempts);
|
||||
.run(
|
||||
record.id,
|
||||
JSON.stringify(record),
|
||||
record.expiresAt,
|
||||
record.consumedAt ?? null,
|
||||
record.attempts,
|
||||
);
|
||||
}
|
||||
|
||||
async getChallenge(id: string): Promise<CaptchaChallengeRecord | undefined> {
|
||||
@@ -96,7 +103,9 @@ export class SqliteCaptchaStore implements CaptchaStore {
|
||||
SET payload = ?, attempts = ?
|
||||
WHERE id = ? AND expires_at > ? AND consumed_at IS NULL AND attempts = ?`,
|
||||
)
|
||||
.run(JSON.stringify(current), current.attempts, id, now, current.attempts - 1) as { changes?: number };
|
||||
.run(JSON.stringify(current), current.attempts, id, now, current.attempts - 1) as {
|
||||
changes?: number;
|
||||
};
|
||||
return result?.changes === 0 ? undefined : current;
|
||||
}
|
||||
|
||||
@@ -134,7 +143,10 @@ export class SqliteCaptchaStore implements CaptchaStore {
|
||||
);
|
||||
}
|
||||
|
||||
async consumeToken(tokenHash: string, now: number): Promise<CaptchaResponseTokenRecord | undefined> {
|
||||
async consumeToken(
|
||||
tokenHash: string,
|
||||
now: number,
|
||||
): Promise<CaptchaResponseTokenRecord | undefined> {
|
||||
const current = await this.getToken(tokenHash);
|
||||
if (!current || current.expiresAt <= now || current.consumedAt) return undefined;
|
||||
current.consumedAt = now;
|
||||
|
||||
Reference in New Issue
Block a user