@aurabase/aurabase-js 0.3.0 → 0.3.1
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/package.json +4 -4
- package/packages/ai/node_modules/.bin/esbuild +0 -19
- package/packages/ai/node_modules/.bin/tsc +0 -22
- package/packages/ai/node_modules/.bin/tsserver +0 -22
- package/packages/ai/node_modules/.bin/tsup +0 -22
- package/packages/ai/node_modules/.bin/tsup-node +0 -22
- package/packages/ai/node_modules/.bin/vite +0 -22
- package/packages/ai/node_modules/.bin/vitest +0 -22
- package/packages/ai/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/packages/ai/src/AiService.ts +0 -226
- package/packages/ai/src/index.ts +0 -18
- package/packages/ai/src/sse.ts +0 -141
- package/packages/ai/src/types.ts +0 -30
- package/packages/ai/tests/chat-stream.test.ts +0 -151
- package/packages/ai/tests/rag-namespaces.test.ts +0 -54
- package/packages/ai/tests/sse.test.ts +0 -69
- package/packages/ai/tsconfig.json +0 -5
- package/packages/ai/tsup.config.ts +0 -11
- package/packages/aurabase/node_modules/.bin/esbuild +0 -19
- package/packages/aurabase/node_modules/.bin/tsc +0 -22
- package/packages/aurabase/node_modules/.bin/tsserver +0 -22
- package/packages/aurabase/node_modules/.bin/tsup +0 -22
- package/packages/aurabase/node_modules/.bin/tsup-node +0 -22
- package/packages/aurabase/node_modules/.bin/vite +0 -22
- package/packages/aurabase/node_modules/.bin/vitest +0 -22
- package/packages/aurabase/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/packages/aurabase/src/AuraClient.ts +0 -237
- package/packages/aurabase/src/index.ts +0 -152
- package/packages/aurabase/src/ssr.ts +0 -156
- package/packages/aurabase/tests/ai-streaming-rag-e2e.test.ts +0 -82
- package/packages/aurabase/tests/ai.test.ts +0 -111
- package/packages/aurabase/tests/auth-admin.test.ts +0 -515
- package/packages/aurabase/tests/auth-e2e.test.ts +0 -135
- package/packages/aurabase/tests/auth-hardening.test.ts +0 -206
- package/packages/aurabase/tests/auth.test.ts +0 -947
- package/packages/aurabase/tests/database.test.ts +0 -230
- package/packages/aurabase/tests/db-types-e2e.test.ts +0 -217
- package/packages/aurabase/tests/dispose.test.ts +0 -23
- package/packages/aurabase/tests/foreign-token.e2e.test.ts +0 -129
- package/packages/aurabase/tests/functions.test.ts +0 -107
- package/packages/aurabase/tests/integration.test.ts +0 -413
- package/packages/aurabase/tests/live-production-validation.js +0 -241
- package/packages/aurabase/tests/live-sdk-production-validation.js +0 -293
- package/packages/aurabase/tests/mocks.ts +0 -139
- package/packages/aurabase/tests/notifications.test.ts +0 -314
- package/packages/aurabase/tests/observability-backup.test.ts +0 -186
- package/packages/aurabase/tests/observability-hook.test.ts +0 -130
- package/packages/aurabase/tests/production-robustness.test.ts +0 -268
- package/packages/aurabase/tests/public-api-surface.test.ts +0 -53
- package/packages/aurabase/tests/query-builder.test.ts +0 -329
- package/packages/aurabase/tests/readme-smoke-e2e.test.ts +0 -231
- package/packages/aurabase/tests/realtime-filter-e2e.test.ts +0 -344
- package/packages/aurabase/tests/refresh-locks.test.ts +0 -210
- package/packages/aurabase/tests/retry-option.test.ts +0 -17
- package/packages/aurabase/tests/rpc-e2e.test.ts +0 -254
- package/packages/aurabase/tests/rs256-local-e2e.test.ts +0 -114
- package/packages/aurabase/tests/rt-alias-public-e2e.test.ts +0 -235
- package/packages/aurabase/tests/rt-http-broadcast-e2e.test.ts +0 -124
- package/packages/aurabase/tests/service-role-guard.test.ts +0 -99
- package/packages/aurabase/tests/ssr.test.ts +0 -91
- package/packages/aurabase/tests/storage-backend-e2e.test.ts +0 -481
- package/packages/aurabase/tests/storage-sdk-parity-e2e.test.ts +0 -104
- package/packages/aurabase/tests/storage-transform-e2e.test.ts +0 -684
- package/packages/aurabase/tests/storage.test.ts +0 -55
- package/packages/aurabase/tests/types/client-generic.test-d.ts +0 -79
- package/packages/aurabase/tests/types/docs-snippets.test-d.ts +0 -571
- package/packages/aurabase/tests/types/error-code.test-d.ts +0 -53
- package/packages/aurabase/tsconfig.json +0 -5
- package/packages/aurabase/tsconfig.test-d.json +0 -5
- package/packages/aurabase/tsup.config.ts +0 -11
- package/packages/aurabase/vitest.config.ts +0 -16
- package/packages/auth/node_modules/.bin/esbuild +0 -19
- package/packages/auth/node_modules/.bin/tsc +0 -22
- package/packages/auth/node_modules/.bin/tsserver +0 -22
- package/packages/auth/node_modules/.bin/tsup +0 -22
- package/packages/auth/node_modules/.bin/tsup-node +0 -22
- package/packages/auth/node_modules/.bin/vite +0 -22
- package/packages/auth/node_modules/.bin/vitest +0 -22
- package/packages/auth/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/packages/auth/src/AuthAdminService.ts +0 -149
- package/packages/auth/src/AuthService.ts +0 -1166
- package/packages/auth/src/SessionManager.ts +0 -92
- package/packages/auth/src/index.ts +0 -17
- package/packages/auth/src/jwks.ts +0 -337
- package/packages/auth/src/pkce.ts +0 -27
- package/packages/auth/src/types.ts +0 -89
- package/packages/auth/tests/auth-lifecycle.test.ts +0 -149
- package/packages/auth/tests/detect-session.test.ts +0 -361
- package/packages/auth/tests/getclaims.test.ts +0 -780
- package/packages/auth/tests/is-mfa-challenge.test.ts +0 -27
- package/packages/auth/tests/password-recovery.test.ts +0 -124
- package/packages/auth/tests/pkce.test.ts +0 -192
- package/packages/auth/tests/session-manager.test.ts +0 -103
- package/packages/auth/tests/set-session.test.ts +0 -139
- package/packages/auth/tests/verify-otp.test.ts +0 -153
- package/packages/auth/tsconfig.json +0 -5
- package/packages/auth/tsup.config.ts +0 -11
- package/packages/core/node_modules/.bin/esbuild +0 -22
- package/packages/core/node_modules/.bin/tsc +0 -22
- package/packages/core/node_modules/.bin/tsserver +0 -22
- package/packages/core/node_modules/.bin/tsup +0 -22
- package/packages/core/node_modules/.bin/tsup-node +0 -22
- package/packages/core/node_modules/.bin/vite +0 -22
- package/packages/core/node_modules/.bin/vitest +0 -22
- package/packages/core/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/packages/core/src/AuraError.ts +0 -89
- package/packages/core/src/BaseService.ts +0 -44
- package/packages/core/src/client.ts +0 -34
- package/packages/core/src/cookie-utils.ts +0 -42
- package/packages/core/src/fetch.ts +0 -435
- package/packages/core/src/index.ts +0 -22
- package/packages/core/src/retry.ts +0 -63
- package/packages/core/src/serialize.ts +0 -6
- package/packages/core/src/stores/BaseAuthStore.ts +0 -164
- package/packages/core/src/stores/LocalAuthStore.ts +0 -199
- package/packages/core/src/types.ts +0 -1042
- package/packages/core/tests/auth-store.test.ts +0 -300
- package/packages/core/tests/error-code.test.ts +0 -61
- package/packages/core/tests/error.test.ts +0 -24
- package/packages/core/tests/fetch.test.ts +0 -286
- package/packages/core/tests/mocks.ts +0 -139
- package/packages/core/tests/observability.test.ts +0 -86
- package/packages/core/tests/refresh-hardening.test.ts +0 -164
- package/packages/core/tests/refresh-observability.test.ts +0 -111
- package/packages/core/tests/retry.test.ts +0 -106
- package/packages/core/tests/serialize.test.ts +0 -12
- package/packages/core/tests/timeout.test.ts +0 -79
- package/packages/core/tsconfig.json +0 -5
- package/packages/core/tsup.config.ts +0 -11
- package/packages/db/node_modules/.bin/esbuild +0 -19
- package/packages/db/node_modules/.bin/tsc +0 -22
- package/packages/db/node_modules/.bin/tsserver +0 -22
- package/packages/db/node_modules/.bin/tsup +0 -22
- package/packages/db/node_modules/.bin/tsup-node +0 -22
- package/packages/db/node_modules/.bin/vite +0 -22
- package/packages/db/node_modules/.bin/vitest +0 -22
- package/packages/db/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/packages/db/src/DatabaseService.ts +0 -170
- package/packages/db/src/QueryBuilder.ts +0 -830
- package/packages/db/src/index.ts +0 -2
- package/packages/db/src/pgrst-types/common/common.ts +0 -86
- package/packages/db/src/pgrst-types/common/rpc.ts +0 -151
- package/packages/db/src/pgrst-types/feature-flags.ts +0 -20
- package/packages/db/src/pgrst-types/types.ts +0 -134
- package/packages/db/src/select-query-parser/parser.ts +0 -479
- package/packages/db/src/select-query-parser/result.ts +0 -553
- package/packages/db/src/select-query-parser/types.ts +0 -132
- package/packages/db/src/select-query-parser/utils.ts +0 -707
- package/packages/db/tests/filters.test.ts +0 -81
- package/packages/db/tests/mutations-filtered.e2e.test.ts +0 -132
- package/packages/db/tests/mutations-filtered.test.ts +0 -188
- package/packages/db/tests/order.test.ts +0 -45
- package/packages/db/tests/rpc.test.ts +0 -41
- package/packages/db/tests/scale/build-large-schema.ts +0 -94
- package/packages/db/tests/scale/scale-compile.test.ts +0 -167
- package/packages/db/tests/schema.test.ts +0 -77
- package/packages/db/tests/single-accept.e2e.test.ts +0 -123
- package/packages/db/tests/single.test.ts +0 -211
- package/packages/db/tests/types/filters.test-d.ts +0 -52
- package/packages/db/tests/types/fixtures.ts +0 -40
- package/packages/db/tests/types/from-views.test-d.ts +0 -18
- package/packages/db/tests/types/mutations.test-d.ts +0 -23
- package/packages/db/tests/types/rpc.test-d.ts +0 -60
- package/packages/db/tests/types/schema-shape.test-d.ts +0 -8
- package/packages/db/tests/types/select-inference.test-d.ts +0 -38
- package/packages/db/tests/vendored/fixtures.ts +0 -83
- package/packages/db/tests/vendored/get-result.test-d.ts +0 -75
- package/packages/db/tsconfig.json +0 -5
- package/packages/db/tsconfig.test-d.json +0 -5
- package/packages/db/tsup.config.ts +0 -11
- package/packages/db/vitest.config.ts +0 -8
- package/packages/functions/node_modules/.bin/esbuild +0 -19
- package/packages/functions/node_modules/.bin/tsc +0 -22
- package/packages/functions/node_modules/.bin/tsserver +0 -22
- package/packages/functions/node_modules/.bin/tsup +0 -22
- package/packages/functions/node_modules/.bin/tsup-node +0 -22
- package/packages/functions/node_modules/.bin/vite +0 -22
- package/packages/functions/node_modules/.bin/vitest +0 -22
- package/packages/functions/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/packages/functions/src/FunctionsService.ts +0 -188
- package/packages/functions/src/errors.ts +0 -70
- package/packages/functions/src/index.ts +0 -6
- package/packages/functions/tests/invoke.test.ts +0 -97
- package/packages/functions/tests/response-type-errors.test.ts +0 -135
- package/packages/functions/tsconfig.json +0 -5
- package/packages/functions/tsup.config.ts +0 -11
- package/packages/gen/node_modules/.bin/esbuild +0 -19
- package/packages/gen/node_modules/.bin/tsc +0 -22
- package/packages/gen/node_modules/.bin/tsserver +0 -22
- package/packages/gen/node_modules/.bin/tsup +0 -22
- package/packages/gen/node_modules/.bin/tsup-node +0 -22
- package/packages/gen/node_modules/.bin/vite +0 -22
- package/packages/gen/node_modules/.bin/vitest +0 -22
- package/packages/gen/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/packages/gen/src/cli.ts +0 -67
- package/packages/gen/src/generate.ts +0 -0
- package/packages/gen/src/index.ts +0 -2
- package/packages/gen/tests/compile.test.ts +0 -213
- package/packages/gen/tests/e2e.test.ts +0 -130
- package/packages/gen/tests/generate.test.ts +0 -396
- package/packages/gen/tsconfig.json +0 -5
- package/packages/gen/tsup.config.ts +0 -11
- package/packages/notifications/node_modules/.bin/esbuild +0 -19
- package/packages/notifications/node_modules/.bin/tsc +0 -22
- package/packages/notifications/node_modules/.bin/tsserver +0 -22
- package/packages/notifications/node_modules/.bin/tsup +0 -22
- package/packages/notifications/node_modules/.bin/tsup-node +0 -22
- package/packages/notifications/node_modules/.bin/vite +0 -22
- package/packages/notifications/node_modules/.bin/vitest +0 -22
- package/packages/notifications/src/NotificationsService.ts +0 -230
- package/packages/notifications/src/index.ts +0 -19
- package/packages/notifications/tsconfig.json +0 -5
- package/packages/notifications/tsup.config.ts +0 -11
- package/packages/realtime/node_modules/.bin/esbuild +0 -19
- package/packages/realtime/node_modules/.bin/tsc +0 -22
- package/packages/realtime/node_modules/.bin/tsserver +0 -22
- package/packages/realtime/node_modules/.bin/tsup +0 -22
- package/packages/realtime/node_modules/.bin/tsup-node +0 -22
- package/packages/realtime/node_modules/.bin/vite +0 -22
- package/packages/realtime/node_modules/.bin/vitest +0 -22
- package/packages/realtime/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/packages/realtime/src/AuraChannel.ts +0 -485
- package/packages/realtime/src/HeartbeatManager.ts +0 -73
- package/packages/realtime/src/RealtimeService.ts +0 -505
- package/packages/realtime/src/columnFilter.ts +0 -301
- package/packages/realtime/src/index.ts +0 -4
- package/packages/realtime/tests/ack-routing.test.ts +0 -81
- package/packages/realtime/tests/column-filter.test.ts +0 -144
- package/packages/realtime/tests/dispatch.test.ts +0 -191
- package/packages/realtime/tests/heartbeat.test.ts +0 -67
- package/packages/realtime/tests/http-broadcast.test.ts +0 -68
- package/packages/realtime/tests/realtime-token.test.ts +0 -43
- package/packages/realtime/tests/reconnect-race.test.ts +0 -149
- package/packages/realtime/tests/ref-id.test.ts +0 -34
- package/packages/realtime/tests/set-auth.test.ts +0 -70
- package/packages/realtime/tsconfig.json +0 -5
- package/packages/realtime/tsup.config.ts +0 -11
- package/packages/storage/node_modules/.bin/esbuild +0 -19
- package/packages/storage/node_modules/.bin/tsc +0 -22
- package/packages/storage/node_modules/.bin/tsserver +0 -22
- package/packages/storage/node_modules/.bin/tsup +0 -22
- package/packages/storage/node_modules/.bin/tsup-node +0 -22
- package/packages/storage/node_modules/.bin/vite +0 -22
- package/packages/storage/node_modules/.bin/vitest +0 -22
- package/packages/storage/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/packages/storage/src/DownloadBuilder.ts +0 -60
- package/packages/storage/src/StorageService.ts +0 -323
- package/packages/storage/src/index.ts +0 -2
- package/packages/storage/src/path.ts +0 -35
- package/packages/storage/src/transform.ts +0 -15
- package/packages/storage/tests/download.test.ts +0 -64
- package/packages/storage/tests/parity.test.ts +0 -154
- package/packages/storage/tests/path.test.ts +0 -87
- package/packages/storage/tests/transform.test.ts +0 -79
- package/packages/storage/tsconfig.json +0 -5
- package/packages/storage/tsup.config.ts +0 -11
- package/pnpm-workspace.yaml +0 -24
- package/tsconfig.base.json +0 -15
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
export interface SessionManagerOptions {
|
|
2
|
-
channelName: string
|
|
3
|
-
enabled: boolean
|
|
4
|
-
onTick: () => void
|
|
5
|
-
isRefreshDue: () => boolean
|
|
6
|
-
onRemoteMessage: (data: unknown) => void
|
|
7
|
-
tickMs?: number
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Primitive de cycle de vie de session (timers + BroadcastChannel + visibilité).
|
|
12
|
-
* Aucune logique métier auth : `AuthService` fournit les callbacks et pilote `setActive`.
|
|
13
|
-
* Sûr en Node/SSR/RN — tous les globals sont gardés (`typeof … !== 'undefined'`).
|
|
14
|
-
*/
|
|
15
|
-
export class SessionManager {
|
|
16
|
-
private readonly opts: SessionManagerOptions & { tickMs: number }
|
|
17
|
-
private _interval: ReturnType<typeof setInterval> | null = null
|
|
18
|
-
private _channel: BroadcastChannel | null = null
|
|
19
|
-
private _active = false
|
|
20
|
-
private _visHandler: (() => void) | null = null
|
|
21
|
-
|
|
22
|
-
constructor(opts: SessionManagerOptions) {
|
|
23
|
-
this.opts = { tickMs: 30_000, ...opts }
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
get isActive(): boolean {
|
|
27
|
-
return this._active
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
start(): void {
|
|
31
|
-
if (!this.opts.enabled) return
|
|
32
|
-
if (typeof BroadcastChannel !== 'undefined' && !this._channel) {
|
|
33
|
-
this._channel = new BroadcastChannel(this.opts.channelName)
|
|
34
|
-
this._channel.onmessage = (e: MessageEvent) => this.opts.onRemoteMessage(e.data)
|
|
35
|
-
}
|
|
36
|
-
if (typeof document !== 'undefined' && !this._visHandler) {
|
|
37
|
-
this._visHandler = () => {
|
|
38
|
-
if (document.hidden) {
|
|
39
|
-
this._stopInterval()
|
|
40
|
-
} else if (this._active) {
|
|
41
|
-
this._startInterval()
|
|
42
|
-
if (this.opts.isRefreshDue()) this.opts.onTick()
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
document.addEventListener('visibilitychange', this._visHandler)
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
setActive(active: boolean): void {
|
|
50
|
-
this._active = active
|
|
51
|
-
if (!this.opts.enabled) return
|
|
52
|
-
const hidden = typeof document !== 'undefined' && document.hidden
|
|
53
|
-
if (active && !hidden) this._startInterval()
|
|
54
|
-
else this._stopInterval()
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
broadcast(data: unknown): void {
|
|
58
|
-
this._channel?.postMessage(data)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
stop(): void {
|
|
62
|
-
this._stopInterval()
|
|
63
|
-
this._active = false
|
|
64
|
-
if (this._channel) {
|
|
65
|
-
try {
|
|
66
|
-
this._channel.close()
|
|
67
|
-
} catch {
|
|
68
|
-
/* ignore */
|
|
69
|
-
}
|
|
70
|
-
this._channel = null
|
|
71
|
-
}
|
|
72
|
-
if (this._visHandler && typeof document !== 'undefined') {
|
|
73
|
-
document.removeEventListener('visibilitychange', this._visHandler)
|
|
74
|
-
this._visHandler = null
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
private _startInterval(): void {
|
|
79
|
-
if (this._interval) return
|
|
80
|
-
this._interval = setInterval(() => {
|
|
81
|
-
if (this.opts.isRefreshDue()) this.opts.onTick()
|
|
82
|
-
}, this.opts.tickMs)
|
|
83
|
-
;(this._interval as { unref?: () => void }).unref?.()
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
private _stopInterval(): void {
|
|
87
|
-
if (this._interval) {
|
|
88
|
-
clearInterval(this._interval)
|
|
89
|
-
this._interval = null
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export { AuthService, isMfaChallenge } from './AuthService'
|
|
2
|
-
export { AuthAdminService } from './AuthAdminService'
|
|
3
|
-
export { SessionManager } from './SessionManager'
|
|
4
|
-
export type { SessionManagerOptions } from './SessionManager'
|
|
5
|
-
export type {
|
|
6
|
-
VerifyOtpParams,
|
|
7
|
-
EmailOtpType,
|
|
8
|
-
MobileOtpType,
|
|
9
|
-
VerifySignupOtpParams,
|
|
10
|
-
VerifyMagiclinkOtpParams,
|
|
11
|
-
VerifyEmailOtpParams,
|
|
12
|
-
VerifySmsOtpParams,
|
|
13
|
-
VerifyEmailChangeOtpParams,
|
|
14
|
-
VerifyRecoveryOtpParams,
|
|
15
|
-
VerifyInviteOtpParams,
|
|
16
|
-
VerifyPhoneChangeOtpParams,
|
|
17
|
-
} from './types'
|
|
@@ -1,337 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Vérification JWT locale via JWKS (WebCrypto).
|
|
3
|
-
*
|
|
4
|
-
* Contrainte anti-alg-confusion (CRITIQUE) : la vérification locale n'accepte
|
|
5
|
-
* QUE `alg ∈ {RS256, ES256}` (clés asymétriques). Tout autre `alg` (HS256, none,
|
|
6
|
-
* ou JWKS sans clé correspondante) ne donne JAMAIS lieu à une vérification locale
|
|
7
|
-
* avec un secret : l'appelant retombe sur `getUser()` (validation côté serveur).
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
interface CachedJwks {
|
|
11
|
-
keys: JsonWebKey[]
|
|
12
|
-
fetchedAt: number
|
|
13
|
-
maxAgeMs: number
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* État de robustesse JWKS, aligné sur `jose` `createRemoteJWKSet` :
|
|
18
|
-
* - dédup in-flight des fetch concurrents (cf. `fetch.ts:31` single-flight refresh),
|
|
19
|
-
* - cooldown sur refetch forcé (kid inconnu), défaut 30s comme jose `cooldownDuration`,
|
|
20
|
-
* - negative-cache court sur échec de fetch (anti-tempête pendant une panne),
|
|
21
|
-
* - plafond `max-age` (pas de cache figé illimité).
|
|
22
|
-
*
|
|
23
|
-
* SEC-F4 : l'état est CLIENT-SCOPED via un `WeakMap<scope, JwksState>` (même pattern
|
|
24
|
-
* que `fetch.ts` `inflightRefreshes: WeakMap<AuraClientLike, …>`), et non plus des
|
|
25
|
-
* `Map` module-level process-global. Chaque `AuraClient` porte donc son propre cache
|
|
26
|
-
* (comme une instance `jose.createRemoteJWKSet`, qui embarque son cache par instance) :
|
|
27
|
-
* - pas de fuite mémoire SSR multi-tenant (l'état est GC'd avec le client, WeakMap),
|
|
28
|
-
* - isolation stricte entre clients (deux clients distincts ne partagent RIEN),
|
|
29
|
-
* - le `scope` reste un `object` opaque → `jwks.ts` n'a AUCUNE dépendance vers `core`.
|
|
30
|
-
*/
|
|
31
|
-
const MAX_AGE_CAP_MS = 86_400_000 // 24h — borne haute d'un `Cache-Control: max-age`.
|
|
32
|
-
const FORCED_REFETCH_COOLDOWN_MS = 30_000 // aligné jose `cooldownDuration` (30s).
|
|
33
|
-
const NEGATIVE_CACHE_TTL_MS = 10_000 // fenêtre anti-retry pendant une panne de fetch.
|
|
34
|
-
const DEFAULT_MAX_AGE_MS = 600_000 // défaut quand aucun `Cache-Control: max-age`.
|
|
35
|
-
|
|
36
|
-
/** État JWKS d'UN client (caches par baseUrl, cf. supra). */
|
|
37
|
-
interface JwksState {
|
|
38
|
-
cache: Map<string, CachedJwks>
|
|
39
|
-
inflight: Map<string, Promise<JsonWebKey[]>>
|
|
40
|
-
lastFailedAt: Map<string, number>
|
|
41
|
-
lastForcedFetchAt: Map<string, number>
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* État JWKS par client (identité d'objet). `WeakMap` → l'entrée est libérée avec le
|
|
46
|
-
* client (pas de fuite mémoire, pas d'invalidation manuelle nécessaire).
|
|
47
|
-
*/
|
|
48
|
-
const clientStates = new WeakMap<object, JwksState>()
|
|
49
|
-
|
|
50
|
-
/** Récupère (ou crée paresseusement) l'état JWKS du `scope` (le client). */
|
|
51
|
-
function stateFor(scope: object): JwksState {
|
|
52
|
-
let s = clientStates.get(scope)
|
|
53
|
-
if (!s) {
|
|
54
|
-
s = {
|
|
55
|
-
cache: new Map(),
|
|
56
|
-
inflight: new Map(),
|
|
57
|
-
lastFailedAt: new Map(),
|
|
58
|
-
lastForcedFetchAt: new Map(),
|
|
59
|
-
}
|
|
60
|
-
clientStates.set(scope, s)
|
|
61
|
-
}
|
|
62
|
-
return s
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* @deprecated SEC-F4 : le cache JWKS est désormais CLIENT-SCOPED (`WeakMap` par client)
|
|
67
|
-
* — plus aucun état process-global à vider. Conservé en NO-OP pour compatibilité des
|
|
68
|
-
* appelants existants (chaque test/instance de client a déjà son cache isolé). À
|
|
69
|
-
* retirer une fois les appels supprimés.
|
|
70
|
-
*/
|
|
71
|
-
export function __resetJwksCache(): void {
|
|
72
|
-
// no-op : plus d'état global (voir stateFor / clientStates).
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
interface DecodedJwt {
|
|
76
|
-
header: { alg?: string; kid?: string; typ?: string; [k: string]: unknown }
|
|
77
|
-
payload: { exp?: number; nbf?: number; [k: string]: unknown }
|
|
78
|
-
signingInput: string
|
|
79
|
-
signature: Uint8Array
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function b64urlToBytes(s: string): Uint8Array {
|
|
83
|
-
const b64 = s.replace(/-/g, '+').replace(/_/g, '/') + '='.repeat((4 - (s.length % 4)) % 4)
|
|
84
|
-
const bin = atob(b64)
|
|
85
|
-
const out = new Uint8Array(bin.length)
|
|
86
|
-
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i)
|
|
87
|
-
return out
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function decodeJwt(jwt: string): DecodedJwt {
|
|
91
|
-
const [h, p, s] = jwt.split('.')
|
|
92
|
-
if (!h || !p || !s) throw new Error('malformed jwt')
|
|
93
|
-
const dec = new TextDecoder()
|
|
94
|
-
return {
|
|
95
|
-
header: JSON.parse(dec.decode(b64urlToBytes(h))),
|
|
96
|
-
payload: JSON.parse(dec.decode(b64urlToBytes(p))),
|
|
97
|
-
signingInput: `${h}.${p}`,
|
|
98
|
-
signature: b64urlToBytes(s),
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function parseMaxAge(cc: string | null): number | null {
|
|
103
|
-
const m = cc?.match(/max-age=(\d+)/)
|
|
104
|
-
return m ? Number(m[1]) * 1000 : null
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Fetch réseau réel du JWKS, DÉDUPLIQUÉ par baseUrl (single-flight, même idée que
|
|
109
|
-
* `refreshOnce` dans `fetch.ts`). En cas d'échec (réseau ou HTTP non-2xx), arme le
|
|
110
|
-
* negative-cache et jette `jwks_fetch_failed`. En cas de succès, peuple le cache
|
|
111
|
-
* (max-age plafonné) et purge le negative-cache.
|
|
112
|
-
*/
|
|
113
|
-
function fetchJwksDeduped(
|
|
114
|
-
state: JwksState,
|
|
115
|
-
fetchFn: typeof globalThis.fetch,
|
|
116
|
-
baseUrl: string,
|
|
117
|
-
): Promise<JsonWebKey[]> {
|
|
118
|
-
const existing = state.inflight.get(baseUrl)
|
|
119
|
-
if (existing) return existing
|
|
120
|
-
const p = (async () => {
|
|
121
|
-
try {
|
|
122
|
-
const res = await fetchFn(`${baseUrl}/.well-known/jwks.json`)
|
|
123
|
-
if (!res.ok) throw new Error('jwks_fetch_failed')
|
|
124
|
-
const body = (await res.json()) as { keys?: JsonWebKey[] }
|
|
125
|
-
const parsed = parseMaxAge(res.headers.get('Cache-Control')) ?? DEFAULT_MAX_AGE_MS
|
|
126
|
-
const maxAge = Math.min(parsed, MAX_AGE_CAP_MS) // cap : pas de cache figé illimité.
|
|
127
|
-
const keys = body.keys ?? []
|
|
128
|
-
state.cache.set(baseUrl, { keys, fetchedAt: Date.now(), maxAgeMs: maxAge })
|
|
129
|
-
state.lastFailedAt.delete(baseUrl)
|
|
130
|
-
return keys
|
|
131
|
-
} catch {
|
|
132
|
-
state.lastFailedAt.set(baseUrl, Date.now())
|
|
133
|
-
throw new Error('jwks_fetch_failed')
|
|
134
|
-
}
|
|
135
|
-
})().finally(() => state.inflight.delete(baseUrl))
|
|
136
|
-
state.inflight.set(baseUrl, p)
|
|
137
|
-
return p
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Chargement non forcé : cache-first (max-age plafonné), gardé par le negative-cache
|
|
142
|
-
* (pas de re-fetch en boucle pendant une panne), déduplication des appels concurrents.
|
|
143
|
-
*/
|
|
144
|
-
async function loadJwks(
|
|
145
|
-
state: JwksState,
|
|
146
|
-
fetchFn: typeof globalThis.fetch,
|
|
147
|
-
baseUrl: string,
|
|
148
|
-
): Promise<JsonWebKey[]> {
|
|
149
|
-
const now = Date.now()
|
|
150
|
-
const c = state.cache.get(baseUrl)
|
|
151
|
-
if (c && now - c.fetchedAt < c.maxAgeMs) return c.keys
|
|
152
|
-
const failedAt = state.lastFailedAt.get(baseUrl)
|
|
153
|
-
if (failedAt !== undefined && now - failedAt < NEGATIVE_CACHE_TTL_MS) {
|
|
154
|
-
throw new Error('jwks_fetch_failed')
|
|
155
|
-
}
|
|
156
|
-
return fetchJwksDeduped(state, fetchFn, baseUrl)
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Refetch FORCÉ (kid inconnu → possible rotation). Borné par un cooldown : dans la
|
|
161
|
-
* fenêtre `FORCED_REFETCH_COOLDOWN_MS`, on NE refetch PAS (retourne `null` → l'appelant
|
|
162
|
-
* retombe sur `no_matching_key` sans réseau). Anti-amplification : un token à `kid`
|
|
163
|
-
* aléatoire ne peut pas provoquer un fetch JWKS par appel.
|
|
164
|
-
*/
|
|
165
|
-
async function forcedRefetchJwks(
|
|
166
|
-
state: JwksState,
|
|
167
|
-
fetchFn: typeof globalThis.fetch,
|
|
168
|
-
baseUrl: string,
|
|
169
|
-
): Promise<JsonWebKey[] | null> {
|
|
170
|
-
const now = Date.now()
|
|
171
|
-
const last = state.lastForcedFetchAt.get(baseUrl)
|
|
172
|
-
if (last !== undefined && now - last < FORCED_REFETCH_COOLDOWN_MS) return null
|
|
173
|
-
state.lastForcedFetchAt.set(baseUrl, now)
|
|
174
|
-
const failedAt = state.lastFailedAt.get(baseUrl)
|
|
175
|
-
if (failedAt !== undefined && now - failedAt < NEGATIVE_CACHE_TTL_MS) {
|
|
176
|
-
throw new Error('jwks_fetch_failed')
|
|
177
|
-
}
|
|
178
|
-
return fetchJwksDeduped(state, fetchFn, baseUrl)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
interface AlgParams {
|
|
182
|
-
importAlg: RsaHashedImportParams | EcKeyImportParams
|
|
183
|
-
verifyAlg: AlgorithmIdentifier | EcdsaParams
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// alg → paramètres WebCrypto import/verify. `null` = pas de vérif locale (fallback).
|
|
187
|
-
function algParams(alg: string | undefined): AlgParams | null {
|
|
188
|
-
if (alg === 'RS256') {
|
|
189
|
-
return {
|
|
190
|
-
importAlg: { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' },
|
|
191
|
-
verifyAlg: { name: 'RSASSA-PKCS1-v1_5' },
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
if (alg === 'ES256') {
|
|
195
|
-
return {
|
|
196
|
-
importAlg: { name: 'ECDSA', namedCurve: 'P-256' },
|
|
197
|
-
verifyAlg: { name: 'ECDSA', hash: 'SHA-256' },
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
return null // HS256 / none / autre → jamais de vérif locale avec un secret
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
export type VerifyResult =
|
|
204
|
-
| { ok: true; claims: Record<string, unknown>; header: { alg: string; kid?: string; typ?: string } }
|
|
205
|
-
| { ok: false; code: string }
|
|
206
|
-
|
|
207
|
-
export async function verifyJwtLocal(
|
|
208
|
-
/**
|
|
209
|
-
* SEC-F4 : clé d'isolation du cache JWKS (identité d'objet). L'appelant passe son
|
|
210
|
-
* `client` (n'importe quel `object` opaque) → l'état JWKS est porté par ce client
|
|
211
|
-
* via `WeakMap` (jamais process-global). Garde `jwks.ts` sans dépendance vers `core`.
|
|
212
|
-
*/
|
|
213
|
-
scope: object,
|
|
214
|
-
fetchFn: typeof globalThis.fetch,
|
|
215
|
-
baseUrl: string,
|
|
216
|
-
jwt: string,
|
|
217
|
-
opts: {
|
|
218
|
-
allowExpired?: boolean
|
|
219
|
-
/**
|
|
220
|
-
* Callback d'observabilité (LOT 3, finding I8), appelé à chaque échec de fetch
|
|
221
|
-
* JWKS (réseau ou HTTP non-2xx). Volontairement non typé sur `AuraObservabilityEvent`
|
|
222
|
-
* (core) — `jwks.ts` reste sans dépendance vers `@aurabase/core` ; c'est `AuthService`
|
|
223
|
-
* qui fournit ce callback en le reliant à `emitAuraEvent(client.onEvent, client.debug,
|
|
224
|
-
* {kind:'jwks-fetch-failed', baseUrl})`. Ne doit jamais throw (appelé au mieux-effort).
|
|
225
|
-
*/
|
|
226
|
-
onEvent?: (baseUrl: string) => void
|
|
227
|
-
} = {},
|
|
228
|
-
): Promise<VerifyResult> {
|
|
229
|
-
let d: DecodedJwt
|
|
230
|
-
try {
|
|
231
|
-
d = decodeJwt(jwt)
|
|
232
|
-
} catch {
|
|
233
|
-
return { ok: false, code: 'invalid_jwt' }
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const params = algParams(d.header.alg)
|
|
237
|
-
if (!params) return { ok: false, code: 'unsupported_alg' } // → l'appelant fait le fallback getUser
|
|
238
|
-
|
|
239
|
-
const state = stateFor(scope)
|
|
240
|
-
|
|
241
|
-
// Le kty doit correspondre à l'alg (RS256→RSA, ES256→EC) — y compris sur le
|
|
242
|
-
// match par kid : deux clés peuvent partager un kid après rotation, on ne doit
|
|
243
|
-
// jamais sélectionner une clé EC pour un token RS256 (défense en profondeur).
|
|
244
|
-
const matchesAlg = (k: JsonWebKey): boolean =>
|
|
245
|
-
d.header.alg === 'RS256' ? k.kty === 'RSA' : k.kty === 'EC'
|
|
246
|
-
// Candidats à essayer, du bon `kty` :
|
|
247
|
-
// - AVEC `kid` : on ne retient QUE les clés du kid demandé. Matcher une autre
|
|
248
|
-
// clé « par kty seul » ferait échouer verify() → `signature_invalid` SANS
|
|
249
|
-
// fallback (seul `no_matching_key` déclenche le fallback getUser) ; en rotation
|
|
250
|
-
// (kid absent du JWKS), un token pourtant valide serait rejeté durement.
|
|
251
|
-
// - SANS `kid` : on retient TOUTES les clés du bon `kty` et on tente verify sur
|
|
252
|
-
// chacune (comme jose). En rotation multi-clés sans kid, la 2e clé peut être la
|
|
253
|
-
// bonne → plus de faux `signature_invalid` en ne testant que la première.
|
|
254
|
-
const candidateKeys = (keys: JsonWebKey[]): JsonWebKey[] =>
|
|
255
|
-
d.header.kid
|
|
256
|
-
? keys.filter((k) => (k as { kid?: string }).kid === d.header.kid && matchesAlg(k))
|
|
257
|
-
: keys.filter((k) => matchesAlg(k))
|
|
258
|
-
|
|
259
|
-
let keys: JsonWebKey[]
|
|
260
|
-
try {
|
|
261
|
-
keys = await loadJwks(state, fetchFn, baseUrl)
|
|
262
|
-
} catch {
|
|
263
|
-
try {
|
|
264
|
-
opts.onEvent?.(baseUrl)
|
|
265
|
-
} catch {
|
|
266
|
-
// le callback ne doit jamais throw
|
|
267
|
-
}
|
|
268
|
-
return { ok: false, code: 'jwks_fetch_failed' }
|
|
269
|
-
}
|
|
270
|
-
let candidates = candidateKeys(keys)
|
|
271
|
-
|
|
272
|
-
// Rotation de clés : si aucune clé ne matche le kid demandé, on force UN refetch
|
|
273
|
-
// (borné par cooldown). Le cooldown peut renvoyer `null` → pas de réseau, on
|
|
274
|
-
// retombe sur `no_matching_key` (→ fallback getUser côté appelant).
|
|
275
|
-
if (candidates.length === 0 && d.header.kid) {
|
|
276
|
-
let refetched: JsonWebKey[] | null
|
|
277
|
-
try {
|
|
278
|
-
refetched = await forcedRefetchJwks(state, fetchFn, baseUrl)
|
|
279
|
-
} catch {
|
|
280
|
-
try {
|
|
281
|
-
opts.onEvent?.(baseUrl)
|
|
282
|
-
} catch {
|
|
283
|
-
// le callback ne doit jamais throw
|
|
284
|
-
}
|
|
285
|
-
return { ok: false, code: 'jwks_fetch_failed' }
|
|
286
|
-
}
|
|
287
|
-
if (refetched) {
|
|
288
|
-
keys = refetched
|
|
289
|
-
candidates = candidateKeys(keys)
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
if (candidates.length === 0) return { ok: false, code: 'no_matching_key' }
|
|
293
|
-
|
|
294
|
-
// JWK issu du réseau : un JWK malformé (ou incompatible avec l'algo) fait *jeter*
|
|
295
|
-
// importKey/verify (DataError). On échoue fermé (signature_invalid) — jamais de
|
|
296
|
-
// rejet de promesse (contrat AuraResponse), jamais de fallback qui masquerait un
|
|
297
|
-
// JWKS corrompu. On tente chaque candidat ; le premier verify() vrai l'emporte.
|
|
298
|
-
const signingBytes = new TextEncoder().encode(d.signingInput)
|
|
299
|
-
let valid = false
|
|
300
|
-
for (const jwk of candidates) {
|
|
301
|
-
try {
|
|
302
|
-
const key = await crypto.subtle.importKey('jwk', jwk, params.importAlg, false, ['verify'])
|
|
303
|
-
if (
|
|
304
|
-
await crypto.subtle.verify(
|
|
305
|
-
params.verifyAlg,
|
|
306
|
-
key,
|
|
307
|
-
d.signature as unknown as BufferSource,
|
|
308
|
-
signingBytes,
|
|
309
|
-
)
|
|
310
|
-
) {
|
|
311
|
-
valid = true
|
|
312
|
-
break
|
|
313
|
-
}
|
|
314
|
-
} catch {
|
|
315
|
-
// clé malformée / incompatible → on tente le candidat suivant.
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
if (!valid) return { ok: false, code: 'signature_invalid' }
|
|
319
|
-
|
|
320
|
-
const now = Math.floor(Date.now() / 1000)
|
|
321
|
-
if (!opts.allowExpired && typeof d.payload.exp === 'number' && d.payload.exp < now) {
|
|
322
|
-
return { ok: false, code: 'token_expired' }
|
|
323
|
-
}
|
|
324
|
-
if (typeof d.payload.nbf === 'number' && d.payload.nbf > now + 60) {
|
|
325
|
-
return { ok: false, code: 'token_not_yet_valid' }
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
return {
|
|
329
|
-
ok: true,
|
|
330
|
-
claims: d.payload,
|
|
331
|
-
header: {
|
|
332
|
-
alg: d.header.alg as string,
|
|
333
|
-
kid: d.header.kid,
|
|
334
|
-
typ: d.header.typ,
|
|
335
|
-
},
|
|
336
|
-
}
|
|
337
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
// PKCE (RFC 7636) — génération du `code_verifier` et calcul du `code_challenge`
|
|
2
|
-
// S256 pour le flux OAuth `signInWithOAuth(..., { flowType: 'pkce' })`.
|
|
3
|
-
|
|
4
|
-
function b64url(bytes: Uint8Array): string {
|
|
5
|
-
let s = ''
|
|
6
|
-
for (const b of bytes) s += String.fromCharCode(b)
|
|
7
|
-
return btoa(s).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Génère un `code_verifier` aléatoire haute entropie (64 octets → ~86
|
|
12
|
-
* caractères base64url), dans la plage [43, 128] imposée par RFC 7636.
|
|
13
|
-
*/
|
|
14
|
-
export function generateCodeVerifier(): string {
|
|
15
|
-
const bytes = new Uint8Array(64)
|
|
16
|
-
crypto.getRandomValues(bytes)
|
|
17
|
-
return b64url(bytes)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Calcule `code_challenge = base64url(SHA-256(verifier))` sans padding
|
|
22
|
-
* (méthode `S256`), tel qu'attendu par le backend aura-auth (oauth.rs).
|
|
23
|
-
*/
|
|
24
|
-
export async function codeChallengeS256(verifier: string): Promise<string> {
|
|
25
|
-
const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier))
|
|
26
|
-
return b64url(new Uint8Array(digest))
|
|
27
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
// ---------------------------------------------------------------------------
|
|
2
|
-
// Types du package @aurabase/auth : façade `verifyOtp` (parité @supabase/auth-js).
|
|
3
|
-
// ---------------------------------------------------------------------------
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Types d'OTP « email » (parité `EmailOtpType` de supabase-js). Tous ne sont pas
|
|
7
|
-
* exercables côté backend Aurabase : `invite` n'a aucun endpoint (→ `verifyOtp`
|
|
8
|
-
* lève `otp_type_unsupported`). Conservé dans l'union pour la parité de surface.
|
|
9
|
-
*/
|
|
10
|
-
export type EmailOtpType = 'signup' | 'invite' | 'magiclink' | 'recovery' | 'email_change' | 'email'
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Types d'OTP « mobile » (parité `MobileOtpType` de supabase-js). `phone_change`
|
|
14
|
-
* n'a aucun endpoint backend (→ `otp_type_unsupported`).
|
|
15
|
-
*/
|
|
16
|
-
export type MobileOtpType = 'sms' | 'phone_change'
|
|
17
|
-
|
|
18
|
-
export interface VerifySignupOtpParams {
|
|
19
|
-
type: 'signup'
|
|
20
|
-
/** Jeton reçu par email (lien de confirmation d'inscription). */
|
|
21
|
-
token: string
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface VerifyMagiclinkOtpParams {
|
|
25
|
-
type: 'magiclink'
|
|
26
|
-
/** Jeton du magic link. */
|
|
27
|
-
token: string
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface VerifyEmailOtpParams {
|
|
31
|
-
type: 'email'
|
|
32
|
-
email: string
|
|
33
|
-
/** Code OTP à 6 chiffres reçu par email (mappé sur `code` côté backend). */
|
|
34
|
-
token: string
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface VerifySmsOtpParams {
|
|
38
|
-
type: 'sms'
|
|
39
|
-
phone: string
|
|
40
|
-
/** Code OTP reçu par SMS (mappé sur `code` côté backend). */
|
|
41
|
-
token: string
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface VerifyEmailChangeOtpParams {
|
|
45
|
-
type: 'email_change'
|
|
46
|
-
/** Jeton de confirmation de changement d'email. */
|
|
47
|
-
token: string
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface VerifyRecoveryOtpParams {
|
|
51
|
-
type: 'recovery'
|
|
52
|
-
/** Jeton de récupération reçu par email. */
|
|
53
|
-
token: string
|
|
54
|
-
/**
|
|
55
|
-
* Nouveau mot de passe. REQUIS : le backend `reset-password` fusionne
|
|
56
|
-
* consommation du token + changement de mot de passe (divergence documentée
|
|
57
|
-
* avec supabase-js qui renvoie une session puis attend un `updateUser`).
|
|
58
|
-
*/
|
|
59
|
-
password: string
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** Type de surface (parité) sans endpoint backend → `otp_type_unsupported`. */
|
|
63
|
-
export interface VerifyInviteOtpParams {
|
|
64
|
-
type: 'invite'
|
|
65
|
-
token: string
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/** Type de surface (parité) sans endpoint backend → `otp_type_unsupported`. */
|
|
69
|
-
export interface VerifyPhoneChangeOtpParams {
|
|
70
|
-
type: 'phone_change'
|
|
71
|
-
phone: string
|
|
72
|
-
token: string
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Union discriminée par `type` de la façade `verifyOtp` (parité surface
|
|
77
|
-
* `@supabase/auth-js`). Chaque variante route vers l'endpoint historique
|
|
78
|
-
* correspondant. `invite`/`phone_change` restent dans l'union pour la parité
|
|
79
|
-
* mais lèvent `otp_type_unsupported` tant que le backend ne les expose pas.
|
|
80
|
-
*/
|
|
81
|
-
export type VerifyOtpParams =
|
|
82
|
-
| VerifySignupOtpParams
|
|
83
|
-
| VerifyMagiclinkOtpParams
|
|
84
|
-
| VerifyEmailOtpParams
|
|
85
|
-
| VerifySmsOtpParams
|
|
86
|
-
| VerifyEmailChangeOtpParams
|
|
87
|
-
| VerifyRecoveryOtpParams
|
|
88
|
-
| VerifyInviteOtpParams
|
|
89
|
-
| VerifyPhoneChangeOtpParams
|