@supacloud/lite 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/LICENSE +201 -0
- package/LICENSES/PGLITE-APACHE-2.0.txt +176 -0
- package/LICENSES/TINBASE-MIT.txt +21 -0
- package/README.md +170 -0
- package/RELEASING.md +22 -0
- package/THIRD_PARTY_NOTICES.md +24 -0
- package/dist/cli.js +9018 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8469 -0
- package/dist/project-runtime.d.ts +65 -0
- package/dist/project-runtime.d.ts.map +1 -0
- package/dist/vendor/tinbase/auth/handler.d.ts +140 -0
- package/dist/vendor/tinbase/auth/handler.d.ts.map +1 -0
- package/dist/vendor/tinbase/auth/inbox.d.ts +34 -0
- package/dist/vendor/tinbase/auth/inbox.d.ts.map +1 -0
- package/dist/vendor/tinbase/auth/oauth.d.ts +88 -0
- package/dist/vendor/tinbase/auth/oauth.d.ts.map +1 -0
- package/dist/vendor/tinbase/auth/password.d.ts +9 -0
- package/dist/vendor/tinbase/auth/password.d.ts.map +1 -0
- package/dist/vendor/tinbase/auth/qr.d.ts +9 -0
- package/dist/vendor/tinbase/auth/qr.d.ts.map +1 -0
- package/dist/vendor/tinbase/auth/rate-limit.d.ts +34 -0
- package/dist/vendor/tinbase/auth/rate-limit.d.ts.map +1 -0
- package/dist/vendor/tinbase/auth/redirect.d.ts +21 -0
- package/dist/vendor/tinbase/auth/redirect.d.ts.map +1 -0
- package/dist/vendor/tinbase/auth/settings.d.ts +56 -0
- package/dist/vendor/tinbase/auth/settings.d.ts.map +1 -0
- package/dist/vendor/tinbase/auth/totp.d.ts +20 -0
- package/dist/vendor/tinbase/auth/totp.d.ts.map +1 -0
- package/dist/vendor/tinbase/cron/service.d.ts +47 -0
- package/dist/vendor/tinbase/cron/service.d.ts.map +1 -0
- package/dist/vendor/tinbase/db/bootstrap.d.ts +21 -0
- package/dist/vendor/tinbase/db/bootstrap.d.ts.map +1 -0
- package/dist/vendor/tinbase/db/database.d.ts +168 -0
- package/dist/vendor/tinbase/db/database.d.ts.map +1 -0
- package/dist/vendor/tinbase/db/emulated.d.ts +53 -0
- package/dist/vendor/tinbase/db/emulated.d.ts.map +1 -0
- package/dist/vendor/tinbase/db/engine.d.ts +47 -0
- package/dist/vendor/tinbase/db/engine.d.ts.map +1 -0
- package/dist/vendor/tinbase/db/inspect.d.ts +19 -0
- package/dist/vendor/tinbase/db/inspect.d.ts.map +1 -0
- package/dist/vendor/tinbase/db/pglite-engine.d.ts +9 -0
- package/dist/vendor/tinbase/db/pglite-engine.d.ts.map +1 -0
- package/dist/vendor/tinbase/db/schema-diff.d.ts +32 -0
- package/dist/vendor/tinbase/db/schema-diff.d.ts.map +1 -0
- package/dist/vendor/tinbase/db/sql-compat.d.ts +33 -0
- package/dist/vendor/tinbase/db/sql-compat.d.ts.map +1 -0
- package/dist/vendor/tinbase/functions/deno-shim.d.ts +15 -0
- package/dist/vendor/tinbase/functions/deno-shim.d.ts.map +1 -0
- package/dist/vendor/tinbase/functions/handler.d.ts +36 -0
- package/dist/vendor/tinbase/functions/handler.d.ts.map +1 -0
- package/dist/vendor/tinbase/gen-types.d.ts +23 -0
- package/dist/vendor/tinbase/gen-types.d.ts.map +1 -0
- package/dist/vendor/tinbase/index.d.ts +82 -0
- package/dist/vendor/tinbase/index.d.ts.map +1 -0
- package/dist/vendor/tinbase/jwt.d.ts +31 -0
- package/dist/vendor/tinbase/jwt.d.ts.map +1 -0
- package/dist/vendor/tinbase/log-buffer.d.ts +28 -0
- package/dist/vendor/tinbase/log-buffer.d.ts.map +1 -0
- package/dist/vendor/tinbase/net/service.d.ts +72 -0
- package/dist/vendor/tinbase/net/service.d.ts.map +1 -0
- package/dist/vendor/tinbase/node/bun-server.d.ts +23 -0
- package/dist/vendor/tinbase/node/bun-server.d.ts.map +1 -0
- package/dist/vendor/tinbase/node/bundle-function.d.ts +8 -0
- package/dist/vendor/tinbase/node/bundle-function.d.ts.map +1 -0
- package/dist/vendor/tinbase/node/config-toml.d.ts +34 -0
- package/dist/vendor/tinbase/node/config-toml.d.ts.map +1 -0
- package/dist/vendor/tinbase/node/fs-driver.d.ts +27 -0
- package/dist/vendor/tinbase/node/fs-driver.d.ts.map +1 -0
- package/dist/vendor/tinbase/node/load-config.d.ts +82 -0
- package/dist/vendor/tinbase/node/load-config.d.ts.map +1 -0
- package/dist/vendor/tinbase/node/load-functions.d.ts +24 -0
- package/dist/vendor/tinbase/node/load-functions.d.ts.map +1 -0
- package/dist/vendor/tinbase/node/project.d.ts +21 -0
- package/dist/vendor/tinbase/node/project.d.ts.map +1 -0
- package/dist/vendor/tinbase/node/server-shared.d.ts +10 -0
- package/dist/vendor/tinbase/node/server-shared.d.ts.map +1 -0
- package/dist/vendor/tinbase/realtime/engine.d.ts +82 -0
- package/dist/vendor/tinbase/realtime/engine.d.ts.map +1 -0
- package/dist/vendor/tinbase/rest/build.d.ts +101 -0
- package/dist/vendor/tinbase/rest/build.d.ts.map +1 -0
- package/dist/vendor/tinbase/rest/errors.d.ts +11 -0
- package/dist/vendor/tinbase/rest/errors.d.ts.map +1 -0
- package/dist/vendor/tinbase/rest/handler.d.ts +28 -0
- package/dist/vendor/tinbase/rest/handler.d.ts.map +1 -0
- package/dist/vendor/tinbase/rest/parse.d.ts +95 -0
- package/dist/vendor/tinbase/rest/parse.d.ts.map +1 -0
- package/dist/vendor/tinbase/retention/service.d.ts +41 -0
- package/dist/vendor/tinbase/retention/service.d.ts.map +1 -0
- package/dist/vendor/tinbase/security.d.ts +23 -0
- package/dist/vendor/tinbase/security.d.ts.map +1 -0
- package/dist/vendor/tinbase/storage/driver.d.ts +17 -0
- package/dist/vendor/tinbase/storage/driver.d.ts.map +1 -0
- package/dist/vendor/tinbase/storage/handler.d.ts +76 -0
- package/dist/vendor/tinbase/storage/handler.d.ts.map +1 -0
- package/dist/vendor/tinbase/storage/image-transform.d.ts +38 -0
- package/dist/vendor/tinbase/storage/image-transform.d.ts.map +1 -0
- package/dist/vendor/tinbase/storage/s3-driver.d.ts +36 -0
- package/dist/vendor/tinbase/storage/s3-driver.d.ts.map +1 -0
- package/dist/vendor/tinbase/types.d.ts +171 -0
- package/dist/vendor/tinbase/types.d.ts.map +1 -0
- package/dist/vendor/tinbase/webhooks/service.d.ts +71 -0
- package/dist/vendor/tinbase/webhooks/service.d.ts.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { type TinbaseBackend } from './vendor/tinbase/index.js';
|
|
2
|
+
import { type RunningServer } from './vendor/tinbase/node/bun-server.js';
|
|
3
|
+
import { type ProjectConfig } from './vendor/tinbase/node/load-config.js';
|
|
4
|
+
import { type S3StorageDriverOptions } from './vendor/tinbase/storage/s3-driver.js';
|
|
5
|
+
import type { StorageDriver } from './vendor/tinbase/types.js';
|
|
6
|
+
export interface ProjectSecrets {
|
|
7
|
+
jwtSecret: string;
|
|
8
|
+
vaultKey: string;
|
|
9
|
+
createdAt: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ProjectPaths {
|
|
12
|
+
projectDir: string;
|
|
13
|
+
stateDir: string;
|
|
14
|
+
dataDir?: string;
|
|
15
|
+
storageDir: string;
|
|
16
|
+
secretsFile: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ProjectRuntimeOptions {
|
|
19
|
+
projectDir?: string;
|
|
20
|
+
stateDir?: string;
|
|
21
|
+
dataDir?: string;
|
|
22
|
+
storageDir?: string;
|
|
23
|
+
storageBackend?: ConfiguredStorageBackend;
|
|
24
|
+
storageDriver?: StorageDriver;
|
|
25
|
+
s3?: S3StorageDriverOptions;
|
|
26
|
+
host?: string;
|
|
27
|
+
port?: number;
|
|
28
|
+
apiUrl?: string;
|
|
29
|
+
siteUrl?: string;
|
|
30
|
+
memory?: boolean;
|
|
31
|
+
applyMigrations?: boolean;
|
|
32
|
+
includeFunctions?: boolean;
|
|
33
|
+
includeWebhooks?: boolean;
|
|
34
|
+
includeSeed?: boolean;
|
|
35
|
+
log?: (message: string) => void;
|
|
36
|
+
}
|
|
37
|
+
export interface ProjectBackend {
|
|
38
|
+
backend: TinbaseBackend;
|
|
39
|
+
config: ProjectConfig;
|
|
40
|
+
paths: ProjectPaths;
|
|
41
|
+
host: string;
|
|
42
|
+
port: number;
|
|
43
|
+
url: string;
|
|
44
|
+
migrationCount: number;
|
|
45
|
+
functionNames: string[];
|
|
46
|
+
webhookCount: number;
|
|
47
|
+
storageBackend: StorageBackend;
|
|
48
|
+
}
|
|
49
|
+
export type StorageBackend = 'fs' | 'memory' | 's3' | 'custom';
|
|
50
|
+
export type ConfiguredStorageBackend = Exclude<StorageBackend, 'custom'>;
|
|
51
|
+
export interface RunningProjectServer extends ProjectBackend {
|
|
52
|
+
server: RunningServer;
|
|
53
|
+
close: () => Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
export declare function resolveProjectPaths(options?: ProjectRuntimeOptions): ProjectPaths;
|
|
56
|
+
export declare function assertResetPathsSafe(paths: ProjectPaths): Promise<void>;
|
|
57
|
+
export declare function ensureProjectSecrets(paths: ProjectPaths): Promise<ProjectSecrets>;
|
|
58
|
+
export declare function mintProjectKeys(jwtSecret: string): Promise<{
|
|
59
|
+
anonKey: string;
|
|
60
|
+
serviceRoleKey: string;
|
|
61
|
+
}>;
|
|
62
|
+
export declare function createProjectBackend(options?: ProjectRuntimeOptions): Promise<ProjectBackend>;
|
|
63
|
+
export declare function resolveStorageBackend(value?: ConfiguredStorageBackend): ConfiguredStorageBackend;
|
|
64
|
+
export declare function startProjectServer(options?: ProjectRuntimeOptions): Promise<RunningProjectServer>;
|
|
65
|
+
//# sourceMappingURL=project-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-runtime.d.ts","sourceRoot":"","sources":["../src/project-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GoTrue-compatible auth endpoints (/auth/v1/*) - the subset supabase-js
|
|
3
|
+
* uses for email/password auth, sessions, and admin user management.
|
|
4
|
+
*/
|
|
5
|
+
import type { Database } from '../db/database.js';
|
|
6
|
+
import type { Mailer, RequestContext } from '../types.js';
|
|
7
|
+
import { type OAuthProviderConfig } from './oauth.js';
|
|
8
|
+
import { type AuthSettings } from './settings.js';
|
|
9
|
+
import { RateLimiter } from './rate-limit.js';
|
|
10
|
+
/** Construction-time config for {@link AuthHandler}. */
|
|
11
|
+
export interface AuthConfig {
|
|
12
|
+
/** HS256 secret used to sign and verify access tokens */
|
|
13
|
+
jwtSecret: string;
|
|
14
|
+
/** public API URL of this instance; used as issuer, OAuth callback, and email-link base */
|
|
15
|
+
apiUrl: string;
|
|
16
|
+
/** frontend URL used as the default redirect target */
|
|
17
|
+
siteUrl: string;
|
|
18
|
+
/** Access-token lifetime in seconds. */
|
|
19
|
+
jwtExpiry: number;
|
|
20
|
+
/** Force sign-out after this many seconds (config.toml auth.sessions.timebox). Caps session lifetime. */
|
|
21
|
+
sessionTimeboxSeconds?: number;
|
|
22
|
+
/** Reject refresh after this many seconds without refresh activity. */
|
|
23
|
+
sessionInactivitySeconds?: number;
|
|
24
|
+
/** sends outgoing auth email (magic links, OTP codes, recovery) */
|
|
25
|
+
mailer: Mailer;
|
|
26
|
+
/** OAuth providers to enable, keyed by provider name (google, github, …) */
|
|
27
|
+
oauthProviders?: Record<string, OAuthProviderConfig>;
|
|
28
|
+
/** injectable fetch for the OAuth provider calls (tests use a mock provider) */
|
|
29
|
+
oauthFetch?: typeof fetch;
|
|
30
|
+
/**
|
|
31
|
+
* Additional redirect targets allowed beyond the site URL's own origin
|
|
32
|
+
* (GoTrue's URI_ALLOW_LIST). Entries may use `*`/`**` globs. A `redirect_to`
|
|
33
|
+
* that matches neither the site origin nor an entry falls back to the site URL.
|
|
34
|
+
*/
|
|
35
|
+
uriAllowList?: string[];
|
|
36
|
+
/**
|
|
37
|
+
* Enforce the redirect allowlist strictly. Off for local dev (any well-formed
|
|
38
|
+
* URL is honored, like `supabase start`); the backend turns it on when
|
|
39
|
+
* network-exposed so redirects can't leave the allowed origins.
|
|
40
|
+
*/
|
|
41
|
+
enforceRedirectAllowList?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Runtime-mutable toggles (signups, anonymous users, autoconfirm…). The
|
|
44
|
+
* admin API mutates this same object in place, so changes apply instantly.
|
|
45
|
+
*/
|
|
46
|
+
settings?: AuthSettings;
|
|
47
|
+
/**
|
|
48
|
+
* Rate limiter for login/signup/OTP/recovery. Defaults to a fresh in-memory
|
|
49
|
+
* limiter with GoTrue-shaped windows; pass `null` to disable (e.g. tests).
|
|
50
|
+
*/
|
|
51
|
+
rateLimiter?: RateLimiter | null;
|
|
52
|
+
}
|
|
53
|
+
interface UserRow {
|
|
54
|
+
id: string;
|
|
55
|
+
aud: string | null;
|
|
56
|
+
role: string | null;
|
|
57
|
+
email: string | null;
|
|
58
|
+
encrypted_password: string | null;
|
|
59
|
+
email_confirmed_at: Date | string | null;
|
|
60
|
+
last_sign_in_at: Date | string | null;
|
|
61
|
+
raw_app_meta_data: Record<string, unknown> | null;
|
|
62
|
+
raw_user_meta_data: Record<string, unknown> | null;
|
|
63
|
+
created_at: Date | string | null;
|
|
64
|
+
updated_at: Date | string | null;
|
|
65
|
+
phone: string | null;
|
|
66
|
+
phone_confirmed_at: Date | string | null;
|
|
67
|
+
is_anonymous: boolean | null;
|
|
68
|
+
}
|
|
69
|
+
/** Routes and services the GoTrue-compatible `/auth/v1/*` endpoints. */
|
|
70
|
+
export declare class AuthHandler {
|
|
71
|
+
private db;
|
|
72
|
+
private config;
|
|
73
|
+
private oauth;
|
|
74
|
+
/** Shared, runtime-mutable settings - read on every request, never copied. */
|
|
75
|
+
private settings;
|
|
76
|
+
private rateLimiter;
|
|
77
|
+
constructor(db: Database, config: AuthConfig);
|
|
78
|
+
/**
|
|
79
|
+
* Enforce the rate limit for `action`, keyed by client address. Returns a 429
|
|
80
|
+
* (GoTrue's `over_request_rate_limit`) when exceeded, else null to proceed.
|
|
81
|
+
*/
|
|
82
|
+
private limit;
|
|
83
|
+
/** Stop background timers (rate-limiter sweep). Called on backend close. */
|
|
84
|
+
stop(): void;
|
|
85
|
+
/** Dispatch one `/auth/v1/*` request. Any thrown error becomes a 500 `unexpected_failure`. */
|
|
86
|
+
handle(req: Request, ctx: RequestContext, url: URL): Promise<Response>;
|
|
87
|
+
private signup;
|
|
88
|
+
private token;
|
|
89
|
+
private getUser;
|
|
90
|
+
private updateUser;
|
|
91
|
+
private logout;
|
|
92
|
+
private issueToken;
|
|
93
|
+
private sendOtp;
|
|
94
|
+
private sendRecovery;
|
|
95
|
+
/** Max wrong guesses for a one-time code before its tokens are invalidated. */
|
|
96
|
+
private static readonly MAX_OTP_ATTEMPTS;
|
|
97
|
+
private redeem;
|
|
98
|
+
private verifyToken;
|
|
99
|
+
private verifyLink;
|
|
100
|
+
private admin;
|
|
101
|
+
/**
|
|
102
|
+
* Append a security event to auth.audit_log_entries (GoTrue-compatible
|
|
103
|
+
* payload). Best-effort: a logging failure never breaks the request.
|
|
104
|
+
*/
|
|
105
|
+
private audit;
|
|
106
|
+
/**
|
|
107
|
+
* Export everything held about one user across the auth schema, for a GDPR
|
|
108
|
+
* right-of-access / portability request. Credentials (password hash, MFA
|
|
109
|
+
* secrets, raw token values) are deliberately omitted - they are not personal
|
|
110
|
+
* data to hand back and exporting them would leak secrets.
|
|
111
|
+
*/
|
|
112
|
+
private exportUser;
|
|
113
|
+
/**
|
|
114
|
+
* Erase a user (GDPR right to erasure). Deletes the user row; auth.identities,
|
|
115
|
+
* refresh_tokens, one_time_tokens, flow_state, and mfa_factors/challenges are
|
|
116
|
+
* removed by their ON DELETE CASCADE foreign keys. Returns a 404 if the user
|
|
117
|
+
* doesn't exist and a summary of what was erased.
|
|
118
|
+
*
|
|
119
|
+
* Note: storage.objects.owner has no FK to auth.users, so object rows/bytes
|
|
120
|
+
* owned by the user are not removed here - see COMPLIANCE.md for the
|
|
121
|
+
* storage-erasure step the operator must run.
|
|
122
|
+
*/
|
|
123
|
+
private eraseUser;
|
|
124
|
+
private enrollFactor;
|
|
125
|
+
private challengeFactor;
|
|
126
|
+
private verifyFactor;
|
|
127
|
+
private unenrollFactor;
|
|
128
|
+
private getUserFactors;
|
|
129
|
+
/** GoTrue-shaped identities for a user (linked providers), from auth.identities. */
|
|
130
|
+
private getUserIdentities;
|
|
131
|
+
private userFromBearer;
|
|
132
|
+
private claimsFromBearer;
|
|
133
|
+
/** Shape a user row into the GoTrue user object supabase-js expects. */
|
|
134
|
+
userJson(u: UserRow, factors?: Record<string, unknown>[], identities?: Record<string, unknown>[]): Record<string, unknown>;
|
|
135
|
+
/** Session tokens for a bare user id (used by the OAuth implicit callback). */
|
|
136
|
+
private sessionTokensFor;
|
|
137
|
+
private sessionFor;
|
|
138
|
+
}
|
|
139
|
+
export {};
|
|
140
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../src/vendor/tinbase/auth/handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local email inbox - the tinbase equivalent of Supabase local's Inbucket /
|
|
3
|
+
* Mailpit. When no custom mailer is configured, outgoing auth emails (magic
|
|
4
|
+
* links, OTP codes, password recovery, email-change confirmations) are captured
|
|
5
|
+
* in memory and viewable at /inbox, so you can test those flows locally without
|
|
6
|
+
* a real SMTP server.
|
|
7
|
+
*
|
|
8
|
+
* Dev-only by nature: it exposes email contents (including sign-in links) with
|
|
9
|
+
* no auth, exactly like Inbucket. Not for production - provide your own
|
|
10
|
+
* `mailer` there and no inbox is mounted.
|
|
11
|
+
*/
|
|
12
|
+
import type { MailMessage, Mailer } from '../types.js';
|
|
13
|
+
/** A captured message plus the link/code extracted from its body for the inbox UI. */
|
|
14
|
+
export interface InboxEntry extends MailMessage {
|
|
15
|
+
id: string;
|
|
16
|
+
created_at: string;
|
|
17
|
+
/** first URL found in the body (the magic/confirm/recovery link), if any */
|
|
18
|
+
link: string | null;
|
|
19
|
+
/** first 6-digit code found in the body (the OTP), if any */
|
|
20
|
+
code: string | null;
|
|
21
|
+
}
|
|
22
|
+
/** In-memory {@link Mailer} that captures the most recent {@link CAP} messages and serves the /inbox UI. */
|
|
23
|
+
export declare class InboxMailer implements Mailer {
|
|
24
|
+
private passthrough?;
|
|
25
|
+
private messages;
|
|
26
|
+
/** `passthrough` still receives every message (e.g. to also log to console). */
|
|
27
|
+
constructor(passthrough?: ((msg: MailMessage) => void) | undefined);
|
|
28
|
+
send(msg: MailMessage): Promise<void>;
|
|
29
|
+
list(): InboxEntry[];
|
|
30
|
+
clear(): void;
|
|
31
|
+
/** Serve GET /inbox (HTML), GET /inbox/api/messages (JSON), DELETE (clear). */
|
|
32
|
+
serve(req: Request, url: URL): Response;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=inbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../../../src/vendor/tinbase/auth/inbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEtD,sFAAsF;AACtF,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AAID,4GAA4G;AAC5G,qBAAa,WAAY,YAAW,MAAM;IAI5B,OAAO,CAAC,WAAW,CAAC;IAHhC,OAAO,CAAC,QAAQ,CAAmB;IAEnC,gFAAgF;gBAC5D,WAAW,CAAC,GAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,aAAA;IAEtD,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAY3C,IAAI,IAAI,UAAU,EAAE;IAGpB,KAAK,IAAI,IAAI;IAIb,+EAA+E;IAC/E,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,QAAQ;CAkBxC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.0 / OIDC provider support for GoTrue-compatible sign-in.
|
|
3
|
+
*
|
|
4
|
+
* Flow (matches hosted Supabase):
|
|
5
|
+
* GET /authorize?provider=… → 302 to the provider, state persisted
|
|
6
|
+
* provider → GET /callback?code=…&state=…
|
|
7
|
+
* → exchange code for a provider token, fetch the profile, upsert the
|
|
8
|
+
* user + identity, then:
|
|
9
|
+
* - PKCE: redirect to redirect_to?code=<auth_code> (client calls
|
|
10
|
+
* exchangeCodeForSession → POST /token?grant_type=pkce)
|
|
11
|
+
* - implicit: redirect to redirect_to#access_token=…&refresh_token=…
|
|
12
|
+
*/
|
|
13
|
+
import type { Database } from '../db/database.js';
|
|
14
|
+
/** Operator-supplied config for one OAuth provider. Endpoint URLs are optional for presets (google, github). */
|
|
15
|
+
export interface OAuthProviderConfig {
|
|
16
|
+
/** OAuth client id issued by the provider */
|
|
17
|
+
clientId: string;
|
|
18
|
+
/** OAuth client secret issued by the provider */
|
|
19
|
+
clientSecret: string;
|
|
20
|
+
/** Overrides; filled from a preset for known providers (google, github). */
|
|
21
|
+
authorizeUrl?: string;
|
|
22
|
+
/** token endpoint; filled from a preset when omitted */
|
|
23
|
+
tokenUrl?: string;
|
|
24
|
+
/** userinfo endpoint; filled from a preset when omitted */
|
|
25
|
+
userInfoUrl?: string;
|
|
26
|
+
/** space-separated scopes to request; falls back to the preset's */
|
|
27
|
+
scopes?: string;
|
|
28
|
+
/** Map the provider's raw userinfo JSON to a normalized profile. */
|
|
29
|
+
profileMap?: (raw: any) => OAuthProfile;
|
|
30
|
+
}
|
|
31
|
+
/** Normalized profile extracted from a provider's userinfo response. */
|
|
32
|
+
export interface OAuthProfile {
|
|
33
|
+
/** Provider-local user id (becomes auth.identities.provider_id). */
|
|
34
|
+
id: string;
|
|
35
|
+
/** email address the provider returned, if any */
|
|
36
|
+
email?: string;
|
|
37
|
+
/** Whether the provider asserts the email is verified; gated for account linking. */
|
|
38
|
+
emailVerified?: boolean;
|
|
39
|
+
/** display name the provider returned, if any */
|
|
40
|
+
name?: string;
|
|
41
|
+
/** extra provider fields (avatar, username, …) merged into identity_data */
|
|
42
|
+
metadata?: Record<string, unknown>;
|
|
43
|
+
}
|
|
44
|
+
interface ResolvedProvider extends Required<Omit<OAuthProviderConfig, 'profileMap'>> {
|
|
45
|
+
name: string;
|
|
46
|
+
profileMap: (raw: any) => OAuthProfile;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Merge operator config with the built-in preset for `name` into a fully
|
|
50
|
+
* resolved provider.
|
|
51
|
+
*
|
|
52
|
+
* @throws if no endpoint URLs are supplied and no preset exists for `name`.
|
|
53
|
+
*/
|
|
54
|
+
export declare function resolveProvider(name: string, cfg: OAuthProviderConfig): ResolvedProvider;
|
|
55
|
+
/** Drives the OAuth authorize/callback/PKCE flows against the configured providers. */
|
|
56
|
+
export declare class OAuthService {
|
|
57
|
+
private db;
|
|
58
|
+
private apiUrl;
|
|
59
|
+
private siteUrl;
|
|
60
|
+
private fetchImpl;
|
|
61
|
+
private uriAllowList;
|
|
62
|
+
private enforceRedirectAllowList;
|
|
63
|
+
private providers;
|
|
64
|
+
constructor(db: Database, apiUrl: string, siteUrl: string, configs: Record<string, OAuthProviderConfig>, fetchImpl?: typeof fetch, uriAllowList?: string[], enforceRedirectAllowList?: boolean);
|
|
65
|
+
/** Whether a provider by this name is configured. */
|
|
66
|
+
has(name: string): boolean;
|
|
67
|
+
private callbackUrl;
|
|
68
|
+
/** GET /authorize - persist state, redirect to the provider. */
|
|
69
|
+
authorize(url: URL): Promise<Response>;
|
|
70
|
+
/** GET /callback - exchange code, upsert user+identity, redirect back. */
|
|
71
|
+
callback(url: URL, createSession: (userId: string) => Promise<OAuthSession>): Promise<Response>;
|
|
72
|
+
/** POST /token?grant_type=pkce - exchange an auth code + verifier for a session. */
|
|
73
|
+
exchangePkce(authCode: string, verifier: string): Promise<string | null>;
|
|
74
|
+
private exchangeCode;
|
|
75
|
+
private fetchProfile;
|
|
76
|
+
private upsertUser;
|
|
77
|
+
}
|
|
78
|
+
/** The minimal session the callback puts in the redirect fragment for the implicit flow. */
|
|
79
|
+
export interface OAuthSession {
|
|
80
|
+
/** signed access token (JWT) */
|
|
81
|
+
access_token: string;
|
|
82
|
+
/** opaque refresh token */
|
|
83
|
+
refresh_token: string;
|
|
84
|
+
/** access-token lifetime in seconds */
|
|
85
|
+
expires_in: number;
|
|
86
|
+
}
|
|
87
|
+
export {};
|
|
88
|
+
//# sourceMappingURL=oauth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../../../src/vendor/tinbase/auth/oauth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAIjD,gHAAgH;AAChH,MAAM,WAAW,mBAAmB;IAClC,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAA;IAChB,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAA;IACpB,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oEAAoE;IACpE,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,YAAY,CAAA;CACxC;AAED,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,EAAE,EAAE,MAAM,CAAA;IACV,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,qFAAqF;IACrF,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED,UAAU,gBAAiB,SAAQ,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,YAAY,CAAC,CAAC;IAClF,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,YAAY,CAAA;CACvC;AAyBD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,gBAAgB,CAkBxF;AAED,uFAAuF;AACvF,qBAAa,YAAY;IAIrB,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,OAAO;IAEf,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,wBAAwB;IATlC,OAAO,CAAC,SAAS,CAAsC;gBAG7C,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,EACpC,SAAS,GAAE,OAAO,KAAa,EAC/B,YAAY,GAAE,MAAM,EAAO,EAC3B,wBAAwB,UAAQ;IAO1C,qDAAqD;IACrD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,OAAO,CAAC,WAAW;IAInB,gEAAgE;IAC1D,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;IAgC5C,0EAA0E;IACpE,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;IA0CrG,oFAAoF;IAC9E,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;YAiBhE,YAAY;YAmBZ,YAAY;YAUZ,UAAU;CAwDzB;AAED,4FAA4F;AAC5F,MAAM,WAAW,YAAY;IAC3B,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,2BAA2B;IAC3B,aAAa,EAAE,MAAM,CAAA;IACrB,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAA;CACnB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Bun bcrypt hashing with PBKDF2 verification retained for pre-release Lite databases. */
|
|
2
|
+
/** Hash a password using bcrypt so imported GoTrue-compatible password rows remain usable. */
|
|
3
|
+
export declare function hashPassword(password: string): Promise<string>;
|
|
4
|
+
/**
|
|
5
|
+
* Verify a password against a stored `pbkdf2$…` hash, re-deriving with the
|
|
6
|
+
* salt/iterations embedded in it. Returns false for any malformed hash.
|
|
7
|
+
*/
|
|
8
|
+
export declare function verifyPassword(password: string, stored: string): Promise<boolean>;
|
|
9
|
+
//# sourceMappingURL=password.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../../../src/vendor/tinbase/auth/password.ts"],"names":[],"mappings":"AAAA,2FAA2F;AA0B3F,8FAA8F;AAC9F,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEpE;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA6BvF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal QR Code generator (byte mode, full version/ECC/mask support) used to
|
|
3
|
+
* render the MFA enrollment otpauth:// URI as a scannable SVG. Compact port of
|
|
4
|
+
* Nayuki's public-domain "QR Code generator" algorithm - no dependencies.
|
|
5
|
+
* Source of the algorithm: https://www.nayuki.io/page/qr-code-generator-library
|
|
6
|
+
*/
|
|
7
|
+
/** Encode `text` as a QR SVG data URI (works directly as an <img src>). */
|
|
8
|
+
export declare function qrSvgDataUri(text: string): string;
|
|
9
|
+
//# sourceMappingURL=qr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qr.d.ts","sourceRoot":"","sources":["../../../../src/vendor/tinbase/auth/qr.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA8VH,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGjD"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory sliding-window rate limiter for auth endpoints. GoTrue throttles
|
|
3
|
+
* login/signup/OTP/recovery to blunt brute-force and mail-flooding; tinbase
|
|
4
|
+
* mirrors that with per-key windows and returns the same 429 /
|
|
5
|
+
* `over_request_rate_limit` shape. State is per-process (no external store),
|
|
6
|
+
* which is sufficient for a single-process local backend.
|
|
7
|
+
*/
|
|
8
|
+
/** A single sliding-window limit: at most `limit` hits per `windowMs`. */
|
|
9
|
+
export interface RateLimitRule {
|
|
10
|
+
/** max requests permitted within the window */
|
|
11
|
+
limit: number;
|
|
12
|
+
/** window length in milliseconds */
|
|
13
|
+
windowMs: number;
|
|
14
|
+
}
|
|
15
|
+
/** Default per-endpoint rules, keyed by the logical action being throttled. */
|
|
16
|
+
export declare const DEFAULT_AUTH_RATE_LIMITS: Record<string, RateLimitRule>;
|
|
17
|
+
/** Per-key sliding-window counter with one background sweep to drop stale buckets. */
|
|
18
|
+
export declare class RateLimiter {
|
|
19
|
+
private hits;
|
|
20
|
+
private timer;
|
|
21
|
+
private rules;
|
|
22
|
+
/** `overrides` (e.g. from config.toml auth.rate_limit.*) replace the matching defaults. */
|
|
23
|
+
constructor(overrides?: Record<string, RateLimitRule>);
|
|
24
|
+
/**
|
|
25
|
+
* Record an attempt for `action` by `key` (typically IP + identifier).
|
|
26
|
+
* Returns `null` when allowed, or the seconds until the window frees up when
|
|
27
|
+
* the limit is exceeded.
|
|
28
|
+
*/
|
|
29
|
+
check(action: string, key: string, now?: number): number | null;
|
|
30
|
+
private sweep;
|
|
31
|
+
/** Stop the background sweep timer. */
|
|
32
|
+
stop(): void;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=rate-limit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../../../src/vendor/tinbase/auth/rate-limit.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,0EAA0E;AAC1E,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAA;IACb,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,+EAA+E;AAC/E,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAOlE,CAAA;AAED,sFAAsF;AACtF,qBAAa,WAAW;IACtB,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,KAAK,CAA8C;IAE3D,OAAO,CAAC,KAAK,CAA+B;IAE5C,2FAA2F;gBAC/E,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAM;IAQzD;;;;OAIG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,MAAM,GAAG,IAAI;IAe3E,OAAO,CAAC,KAAK;IAMb,uCAAuC;IACvC,IAAI,IAAI,IAAI;CAIb"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redirect-URL validation, matching GoTrue's URI_ALLOW_LIST behavior: a
|
|
3
|
+
* client-supplied `redirect_to` is only honored when it is same-origin with the
|
|
4
|
+
* site URL or matches a configured allowlist entry. Anything else falls back to
|
|
5
|
+
* the site URL, so a crafted magic-link/OAuth URL can't redirect a victim (and
|
|
6
|
+
* the freshly minted session tokens) to an attacker-controlled origin.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the redirect target: return `requested` when it is allowed, otherwise
|
|
10
|
+
* fall back to `siteUrl`. `requested` is allowed when it is same-origin with
|
|
11
|
+
* `siteUrl` or matches any `allowList` glob.
|
|
12
|
+
*
|
|
13
|
+
* When `enforce` is false (the default for a loopback/local-dev backend), any
|
|
14
|
+
* well-formed absolute URL is honored - matching how `supabase start` lets a
|
|
15
|
+
* dev redirect anywhere locally. The backend sets `enforce` to true once bound
|
|
16
|
+
* to a network-exposed host, at which point the allowlist is strict.
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveRedirect(requested: string | null | undefined, siteUrl: string, allowList?: string[], enforce?: boolean): string;
|
|
19
|
+
/** Whether `requested` is same-origin with `siteUrl` or matches the allowlist. */
|
|
20
|
+
export declare function isAllowedRedirect(requested: string, siteUrl: string, allowList?: string[]): boolean;
|
|
21
|
+
//# sourceMappingURL=redirect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redirect.d.ts","sourceRoot":"","sources":["../../../../src/vendor/tinbase/auth/redirect.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA2BH;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAM,EAAO,EACxB,OAAO,UAAQ,GACd,MAAM,CAYR;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,EAAO,GAAG,OAAO,CAavG"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-mutable auth settings - the knobs Studio's "Sign In / Providers"
|
|
3
|
+
* page toggles. One shared object is created at boot, read by the auth
|
|
4
|
+
* handler on every request, mutated in place by the admin API, and persisted
|
|
5
|
+
* to the auth.config kv table so restarts keep the operator's choices.
|
|
6
|
+
*/
|
|
7
|
+
import type { Database } from '../db/database.js';
|
|
8
|
+
/**
|
|
9
|
+
* Runtime-mutable auth configuration. One shared instance is read by the auth
|
|
10
|
+
* handler on every request and edited in place by the admin API, so changes
|
|
11
|
+
* apply immediately; it is persisted to auth.config to survive restarts.
|
|
12
|
+
*/
|
|
13
|
+
export interface AuthSettings {
|
|
14
|
+
/** When true, new email/password signups are rejected (existing users can still sign in). */
|
|
15
|
+
disableSignup: boolean;
|
|
16
|
+
/** Allow signInAnonymously() to mint temporary users. */
|
|
17
|
+
anonymousUsers: boolean;
|
|
18
|
+
/** Confirm email addresses automatically on signup. When false, users must verify via the emailed link before signing in. */
|
|
19
|
+
autoconfirm: boolean;
|
|
20
|
+
/** Minimum accepted password length (signup, updateUser, admin create). */
|
|
21
|
+
minPasswordLength: number;
|
|
22
|
+
/** Configured OAuth providers the operator has switched off at runtime. */
|
|
23
|
+
disabledProviders: string[];
|
|
24
|
+
/** Digits in emailed OTP codes (config.toml auth.email.otp_length; 6-10). */
|
|
25
|
+
otpLength: number;
|
|
26
|
+
/** OTP / magic-link lifetime in seconds (auth.email.otp_expiry). */
|
|
27
|
+
otpExpirySeconds: number;
|
|
28
|
+
/** Max MFA factors a user may enroll (auth.mfa.max_enrolled_factors). */
|
|
29
|
+
maxEnrolledFactors: number;
|
|
30
|
+
/** Allow TOTP enrollment (auth.mfa.totp.enroll_enabled). */
|
|
31
|
+
totpEnrollEnabled: boolean;
|
|
32
|
+
/** Allow TOTP verification/challenge (auth.mfa.totp.verify_enabled). */
|
|
33
|
+
totpVerifyEnabled: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** Built-in defaults, matching `supabase start`'s permissive local posture (autoconfirm on, anonymous users on). */
|
|
36
|
+
export declare const DEFAULT_AUTH_SETTINGS: AuthSettings;
|
|
37
|
+
/**
|
|
38
|
+
* Resolve the effective auth settings by layering, low precedence first:
|
|
39
|
+
* 1. built-in defaults
|
|
40
|
+
* 2. `defaults` - the committed baseline (config.toml [auth]); portable, in VCS
|
|
41
|
+
* 3. the persisted auth.config row - per-instance live overrides from the studio
|
|
42
|
+
*
|
|
43
|
+
* config.toml stays the source of truth a project commits; the studio's live
|
|
44
|
+
* toggles are overrides on top, so both models coexist.
|
|
45
|
+
*/
|
|
46
|
+
export declare function loadAuthSettings(db: Database, defaults?: Partial<AuthSettings>): Promise<AuthSettings>;
|
|
47
|
+
/** Persist the settings object to auth.config. */
|
|
48
|
+
export declare function saveAuthSettings(db: Database, settings: AuthSettings): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Apply a partial patch onto the shared settings object IN PLACE (so every
|
|
51
|
+
* holder of the reference - the auth handler - sees the change immediately).
|
|
52
|
+
*
|
|
53
|
+
* @returns An error message for an invalid patch, or `null` on success.
|
|
54
|
+
*/
|
|
55
|
+
export declare function applyAuthSettingsPatch(target: AuthSettings, patch: Record<string, unknown>): string | null;
|
|
56
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../../src/vendor/tinbase/auth/settings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAEjD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,6FAA6F;IAC7F,aAAa,EAAE,OAAO,CAAA;IACtB,yDAAyD;IACzD,cAAc,EAAE,OAAO,CAAA;IACvB,6HAA6H;IAC7H,WAAW,EAAE,OAAO,CAAA;IACpB,2EAA2E;IAC3E,iBAAiB,EAAE,MAAM,CAAA;IACzB,2EAA2E;IAC3E,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAA;IACjB,oEAAoE;IACpE,gBAAgB,EAAE,MAAM,CAAA;IACxB,yEAAyE;IACzE,kBAAkB,EAAE,MAAM,CAAA;IAC1B,4DAA4D;IAC5D,iBAAiB,EAAE,OAAO,CAAA;IAC1B,wEAAwE;IACxE,iBAAiB,EAAE,OAAO,CAAA;CAC3B;AAED,oHAAoH;AACpH,eAAO,MAAM,qBAAqB,EAAE,YAWnC,CAAA;AA4BD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,GAAE,OAAO,CAAC,YAAY,CAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAShH;AAED,kDAAkD;AAClD,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAM1F;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CAqC1G"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Encode bytes as unpadded RFC 4648 base32 (the format authenticator apps expect). */
|
|
2
|
+
export declare function base32Encode(bytes: Uint8Array): string;
|
|
3
|
+
/** Decode an unpadded/padded base32 string to bytes (case-insensitive). */
|
|
4
|
+
export declare function base32Decode(input: string): Uint8Array;
|
|
5
|
+
/** A fresh 20-byte (160-bit) base32 secret, the GoTrue/authenticator default. */
|
|
6
|
+
export declare function generateTotpSecret(): string;
|
|
7
|
+
/** Build the otpauth:// URI an authenticator app scans. */
|
|
8
|
+
export declare function otpauthUri(opts: {
|
|
9
|
+
secret: string;
|
|
10
|
+
account: string;
|
|
11
|
+
issuer: string;
|
|
12
|
+
}): string;
|
|
13
|
+
/** Current 6-digit code for a base32 secret (used in tests and self-checks). */
|
|
14
|
+
export declare function totpNow(secretBase32: string, atMs?: number): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Verify a submitted code against the secret, allowing ±`window` steps of
|
|
17
|
+
* clock skew (default ±1 = a 90-second acceptance window, like GoTrue).
|
|
18
|
+
*/
|
|
19
|
+
export declare function verifyTotp(secretBase32: string, code: string, window?: number, atMs?: number): Promise<boolean>;
|
|
20
|
+
//# sourceMappingURL=totp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"totp.d.ts","sourceRoot":"","sources":["../../../../src/vendor/tinbase/auth/totp.ts"],"names":[],"mappings":"AAQA,uFAAuF;AACvF,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CActD;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAgBtD;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AAED,2DAA2D;AAC3D,wBAAgB,UAAU,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAU5F;AAsBD,gFAAgF;AAChF,wBAAsB,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,SAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAGtF;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,SAAI,EAAE,IAAI,SAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CASpH"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-process scheduler that runs the jobs recorded in cron.job - the execution
|
|
3
|
+
* half of our pg_cron emulation (the cron.schedule()/unschedule() SQL functions
|
|
4
|
+
* live in db/emulated.ts). Supports standard 5-field cron expressions and
|
|
5
|
+
* pg_cron's "N seconds" form. Cron fields are matched in UTC, to match hosted
|
|
6
|
+
* pg_cron (which runs in UTC). Runs due job commands as superuser and logs each
|
|
7
|
+
* run to cron.job_run_details.
|
|
8
|
+
*/
|
|
9
|
+
import type { Database } from '../db/database.js';
|
|
10
|
+
/**
|
|
11
|
+
* Polls cron.job on the tick interval and runs any due jobs as superuser,
|
|
12
|
+
* logging each run to cron.job_run_details - the execution half of the pg_cron
|
|
13
|
+
* emulation.
|
|
14
|
+
*/
|
|
15
|
+
export declare class CronService {
|
|
16
|
+
private db;
|
|
17
|
+
/** how often to check for due jobs (ms). Small so "N seconds" jobs are timely. */
|
|
18
|
+
private tickMs;
|
|
19
|
+
private now;
|
|
20
|
+
private timer;
|
|
21
|
+
private lastRun;
|
|
22
|
+
private lastMinute;
|
|
23
|
+
/** The in-flight tick, tracked so stop() can drain it before db.close(). */
|
|
24
|
+
private inFlight;
|
|
25
|
+
constructor(db: Database,
|
|
26
|
+
/** how often to check for due jobs (ms). Small so "N seconds" jobs are timely. */
|
|
27
|
+
tickMs?: number, now?: () => Date);
|
|
28
|
+
/** Begin polling for due jobs on the tick interval; no-op if already running. */
|
|
29
|
+
start(): void;
|
|
30
|
+
/**
|
|
31
|
+
* Stop the scheduler and wait for any in-flight tick to finish before the
|
|
32
|
+
* caller closes the database - the single connection busy-loops if closed
|
|
33
|
+
* while a job query is still queued.
|
|
34
|
+
*/
|
|
35
|
+
stop(): Promise<void>;
|
|
36
|
+
/** Run any due jobs once (also callable directly in tests). */
|
|
37
|
+
tick(): Promise<void>;
|
|
38
|
+
private isDue;
|
|
39
|
+
private run;
|
|
40
|
+
private log;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Match a Date against a standard 5-field cron expression (min hour dom month
|
|
44
|
+
* dow). Fields are evaluated in UTC, matching hosted pg_cron.
|
|
45
|
+
*/
|
|
46
|
+
export declare function cronMatches(expr: string, date: Date): boolean;
|
|
47
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/vendor/tinbase/cron/service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAUjD;;;;GAIG;AACH,qBAAa,WAAW;IAQpB,OAAO,CAAC,EAAE;IACV,kFAAkF;IAClF,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,GAAG;IAVb,OAAO,CAAC,KAAK,CAA8C;IAC3D,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,UAAU,CAA4B;IAC9C,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAA6B;gBAGnC,EAAE,EAAE,QAAQ;IACpB,kFAAkF;IAC1E,MAAM,SAAO,EACb,GAAG,GAAE,MAAM,IAAuB;IAG5C,iFAAiF;IACjF,KAAK,IAAI,IAAI;IAQb;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B,+DAA+D;IACzD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAa3B,OAAO,CAAC,KAAK;YAcC,GAAG;YAYH,GAAG;CAWlB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAe7D"}
|