@feelflow/ffid-sdk 12.0.0 → 12.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/README.md +62 -0
- package/dist/agency/index.d.cts +19 -0
- package/dist/agency/index.d.ts +19 -0
- package/dist/{chunk-OL7KVPQ4.js → chunk-75ISD4I4.js} +73 -12
- package/dist/{chunk-XRWDTYA7.cjs → chunk-LT7FQ7BT.cjs} +74 -11
- package/dist/components/index.cjs +8 -8
- package/dist/components/index.js +1 -1
- package/dist/{ffid-client-DW8_m1_M.d.cts → ffid-client-DMwmK8mM.d.cts} +24 -2
- package/dist/{ffid-client-ByfZA9sJ.d.ts → ffid-client-Dr2KVlIZ.d.ts} +24 -2
- package/dist/index.cjs +99 -97
- package/dist/index.d.cts +31 -4
- package/dist/index.d.ts +31 -4
- package/dist/index.js +3 -7
- package/dist/server/index.cjs +262 -14
- package/dist/server/index.d.cts +146 -3
- package/dist/server/index.d.ts +146 -3
- package/dist/server/index.js +254 -16
- package/dist/server/test/index.d.cts +1 -1
- package/dist/server/test/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/server/index.cjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var chunkMDHKSVLP_cjs = require('../chunk-MDHKSVLP.cjs');
|
|
4
4
|
var jose = require('jose');
|
|
5
|
+
var zod = require('zod');
|
|
5
6
|
|
|
6
7
|
// src/auth/token-store.ts
|
|
7
8
|
var STORAGE_KEY = "ffid_tokens";
|
|
@@ -310,13 +311,13 @@ var HTTP_SERVER_ERROR_MIN = 500;
|
|
|
310
311
|
var HTTP_SERVER_ERROR_LIMIT = 600;
|
|
311
312
|
function createVerifyAccessToken(deps) {
|
|
312
313
|
const { authMode, baseUrl, serviceCode, serviceApiKey, verifyStrategy, logger, createError, errorCodes, cache, timeout } = deps;
|
|
313
|
-
let
|
|
314
|
+
let jwtVerify3 = null;
|
|
314
315
|
let cacheReadFailureEscalated = false;
|
|
315
316
|
let cacheWriteFailureEscalated = false;
|
|
316
317
|
let missingSubtleCryptoLogged = false;
|
|
317
318
|
function getJwtVerifier() {
|
|
318
|
-
if (!
|
|
319
|
-
|
|
319
|
+
if (!jwtVerify3) {
|
|
320
|
+
jwtVerify3 = createJwtVerifier({
|
|
320
321
|
baseUrl,
|
|
321
322
|
serviceCode,
|
|
322
323
|
logger,
|
|
@@ -326,7 +327,7 @@ function createVerifyAccessToken(deps) {
|
|
|
326
327
|
errorCodes
|
|
327
328
|
});
|
|
328
329
|
}
|
|
329
|
-
return
|
|
330
|
+
return jwtVerify3;
|
|
330
331
|
}
|
|
331
332
|
async function verifyAccessToken(accessToken, options) {
|
|
332
333
|
if (authMode !== "service-key") {
|
|
@@ -574,7 +575,8 @@ function createBillingMethods(deps) {
|
|
|
574
575
|
subscriptionId: params.subscriptionId,
|
|
575
576
|
successUrl: params.successUrl,
|
|
576
577
|
cancelUrl: params.cancelUrl,
|
|
577
|
-
...params.planId ? { planId: params.planId } : {}
|
|
578
|
+
...params.planId ? { planId: params.planId } : {},
|
|
579
|
+
...params.quantity !== void 0 ? { quantity: params.quantity } : {}
|
|
578
580
|
})
|
|
579
581
|
}
|
|
580
582
|
);
|
|
@@ -1387,7 +1389,7 @@ var FFID_ORGANIZATION_PROFILE_ERROR_CODES = {
|
|
|
1387
1389
|
};
|
|
1388
1390
|
|
|
1389
1391
|
// src/client/version-check.ts
|
|
1390
|
-
var SDK_VERSION = "12.
|
|
1392
|
+
var SDK_VERSION = "12.2.0";
|
|
1391
1393
|
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
1392
1394
|
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
1393
1395
|
function sdkHeaders() {
|
|
@@ -3336,24 +3338,44 @@ function createContractWizardMethods(deps) {
|
|
|
3336
3338
|
};
|
|
3337
3339
|
}
|
|
3338
3340
|
|
|
3341
|
+
// src/newsletter/types.ts
|
|
3342
|
+
var FFID_NEWSLETTER_TYPES = ["inquiry_followup", "general"];
|
|
3343
|
+
|
|
3339
3344
|
// src/newsletter/ffid-newsletter-client.ts
|
|
3340
3345
|
var EXT_SUBSCRIBE_ENDPOINT2 = "/api/v1/ext/newsletter/subscribe";
|
|
3341
3346
|
var CONFIRM_ENDPOINT = "/api/newsletter/confirm";
|
|
3342
3347
|
var UNSUBSCRIBE_ENDPOINT = "/api/newsletter/unsubscribe";
|
|
3343
3348
|
var DISPATCH_ENDPOINT = "/api/v1/newsletter/dispatch";
|
|
3349
|
+
var PUBLIC_TOKEN_TIMEOUT_MS = 3e4;
|
|
3350
|
+
var subscribeResponseSchema = zod.z.object({
|
|
3351
|
+
ok: zod.z.literal(true),
|
|
3352
|
+
requiresConfirmation: zod.z.boolean(),
|
|
3353
|
+
requiresSignIn: zod.z.boolean(),
|
|
3354
|
+
confirmationEmailPending: zod.z.boolean(),
|
|
3355
|
+
requestId: zod.z.uuid().optional()
|
|
3356
|
+
}).refine(
|
|
3357
|
+
(value) => [
|
|
3358
|
+
value.requiresConfirmation,
|
|
3359
|
+
value.requiresSignIn,
|
|
3360
|
+
value.confirmationEmailPending
|
|
3361
|
+
].filter(Boolean).length <= 1
|
|
3362
|
+
);
|
|
3344
3363
|
function trimOrEmpty(s) {
|
|
3345
3364
|
return typeof s === "string" ? s.trim() : "";
|
|
3346
3365
|
}
|
|
3347
3366
|
async function postPublic(url, init, opts) {
|
|
3348
3367
|
let response;
|
|
3349
3368
|
try {
|
|
3350
|
-
response = await fetch(url,
|
|
3351
|
-
|
|
3369
|
+
response = await fetch(url, {
|
|
3370
|
+
...init,
|
|
3371
|
+
credentials: "omit",
|
|
3372
|
+
redirect: "error",
|
|
3373
|
+
cache: "no-store",
|
|
3374
|
+
signal: AbortSignal.timeout(PUBLIC_TOKEN_TIMEOUT_MS)
|
|
3375
|
+
});
|
|
3376
|
+
} catch {
|
|
3352
3377
|
return {
|
|
3353
|
-
error: opts.createError(
|
|
3354
|
-
"NETWORK_ERROR",
|
|
3355
|
-
err instanceof Error ? err.message : "\u30CD\u30C3\u30C8\u30EF\u30FC\u30AF\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"
|
|
3356
|
-
)
|
|
3378
|
+
error: opts.createError("NETWORK_ERROR", opts.fallbackMessage)
|
|
3357
3379
|
};
|
|
3358
3380
|
}
|
|
3359
3381
|
if (!response.ok) {
|
|
@@ -3380,7 +3402,7 @@ async function postPublic(url, init, opts) {
|
|
|
3380
3402
|
}
|
|
3381
3403
|
function createNewsletterMethods(deps) {
|
|
3382
3404
|
const { fetchWithAuth, baseUrl, createError } = deps;
|
|
3383
|
-
async function subscribe(params) {
|
|
3405
|
+
async function subscribe(params, options = {}) {
|
|
3384
3406
|
const email = trimOrEmpty(params.email);
|
|
3385
3407
|
const source = trimOrEmpty(params.source);
|
|
3386
3408
|
if (!email) {
|
|
@@ -3397,10 +3419,19 @@ function createNewsletterMethods(deps) {
|
|
|
3397
3419
|
)
|
|
3398
3420
|
};
|
|
3399
3421
|
}
|
|
3400
|
-
|
|
3422
|
+
if (options.idempotencyKey !== void 0 && !zod.z.uuid().safeParse(options.idempotencyKey).success) {
|
|
3423
|
+
return {
|
|
3424
|
+
error: createError(
|
|
3425
|
+
"INVALID_IDEMPOTENCY_KEY",
|
|
3426
|
+
"idempotencyKey \u306B\u306F UUID \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"
|
|
3427
|
+
)
|
|
3428
|
+
};
|
|
3429
|
+
}
|
|
3430
|
+
const response = await fetchWithAuth(
|
|
3401
3431
|
EXT_SUBSCRIBE_ENDPOINT2,
|
|
3402
3432
|
{
|
|
3403
3433
|
method: "POST",
|
|
3434
|
+
...options.idempotencyKey ? { headers: { "Idempotency-Key": options.idempotencyKey } } : {},
|
|
3404
3435
|
body: JSON.stringify({
|
|
3405
3436
|
email,
|
|
3406
3437
|
types: params.types,
|
|
@@ -3409,6 +3440,23 @@ function createNewsletterMethods(deps) {
|
|
|
3409
3440
|
})
|
|
3410
3441
|
}
|
|
3411
3442
|
);
|
|
3443
|
+
if (response.error) return response;
|
|
3444
|
+
const parsed = subscribeResponseSchema.safeParse(response.data);
|
|
3445
|
+
if (!parsed.success)
|
|
3446
|
+
return {
|
|
3447
|
+
error: createError(
|
|
3448
|
+
"PARSE_ERROR",
|
|
3449
|
+
"\u30CB\u30E5\u30FC\u30B9\u30EC\u30BF\u30FC\u767B\u9332\u306E\u5FDC\u7B54\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F"
|
|
3450
|
+
)
|
|
3451
|
+
};
|
|
3452
|
+
if (options.idempotencyKey && parsed.data.requestId !== options.idempotencyKey)
|
|
3453
|
+
return {
|
|
3454
|
+
error: createError(
|
|
3455
|
+
"PARSE_ERROR",
|
|
3456
|
+
"\u30CB\u30E5\u30FC\u30B9\u30EC\u30BF\u30FC\u767B\u9332\u306E\u30EA\u30AF\u30A8\u30B9\u30C8\u8B58\u5225\u5B50\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F"
|
|
3457
|
+
)
|
|
3458
|
+
};
|
|
3459
|
+
return { data: parsed.data };
|
|
3412
3460
|
}
|
|
3413
3461
|
async function confirm(params) {
|
|
3414
3462
|
const token = trimOrEmpty(params.token);
|
|
@@ -3436,6 +3484,16 @@ function createNewsletterMethods(deps) {
|
|
|
3436
3484
|
}
|
|
3437
3485
|
const url = new URL(`${baseUrl}${UNSUBSCRIBE_ENDPOINT}`);
|
|
3438
3486
|
url.searchParams.set("token", token);
|
|
3487
|
+
if (params.type !== void 0) {
|
|
3488
|
+
if (!FFID_NEWSLETTER_TYPES.includes(params.type))
|
|
3489
|
+
return {
|
|
3490
|
+
error: createError(
|
|
3491
|
+
"VALIDATION_ERROR",
|
|
3492
|
+
"\u30CB\u30E5\u30FC\u30B9\u30EC\u30BF\u30FC\u306E\u914D\u4FE1\u7A2E\u5225\u304C\u4E0D\u6B63\u3067\u3059"
|
|
3493
|
+
)
|
|
3494
|
+
};
|
|
3495
|
+
url.searchParams.set("type", params.type);
|
|
3496
|
+
}
|
|
3439
3497
|
return postPublic(
|
|
3440
3498
|
url.toString(),
|
|
3441
3499
|
{ method: "POST" },
|
|
@@ -4865,6 +4923,186 @@ function clear(opts = {}) {
|
|
|
4865
4923
|
}
|
|
4866
4924
|
var sessionCookies = { serialize, read, clear };
|
|
4867
4925
|
|
|
4926
|
+
// src/server/db-token/constants.ts
|
|
4927
|
+
var FFID_DB_TOKEN_ALGORITHM = "ES256";
|
|
4928
|
+
var FFID_DB_TOKEN_ROLE = "authenticated";
|
|
4929
|
+
var FFID_DB_TOKEN_AUDIENCE = "authenticated";
|
|
4930
|
+
var DEFAULT_DB_TOKEN_TTL_SECONDS = 300;
|
|
4931
|
+
var MAX_DB_TOKEN_TTL_SECONDS = 900;
|
|
4932
|
+
var FFID_DB_TOKEN_ORGANIZATION_CLAIM = "organization_id";
|
|
4933
|
+
var FFID_DB_TOKEN_RESERVED_CLAIMS = [
|
|
4934
|
+
"sub",
|
|
4935
|
+
"role",
|
|
4936
|
+
"aud",
|
|
4937
|
+
"iss",
|
|
4938
|
+
"iat",
|
|
4939
|
+
"exp",
|
|
4940
|
+
"nbf",
|
|
4941
|
+
"jti",
|
|
4942
|
+
FFID_DB_TOKEN_ORGANIZATION_CLAIM
|
|
4943
|
+
];
|
|
4944
|
+
var MILLISECONDS_PER_SECOND = 1e3;
|
|
4945
|
+
|
|
4946
|
+
// src/server/db-token/errors.ts
|
|
4947
|
+
var FFID_DB_TOKEN_ERROR_CODES = {
|
|
4948
|
+
/** Signing key is not a private P-256 JWK with a `kid`, or cannot be imported. */
|
|
4949
|
+
INVALID_SIGNING_KEY: "INVALID_SIGNING_KEY",
|
|
4950
|
+
/** `ttlSeconds` is not a positive integer within `MAX_DB_TOKEN_TTL_SECONDS`. */
|
|
4951
|
+
INVALID_TTL: "INVALID_TTL",
|
|
4952
|
+
/** `userId` is not a UUID. */
|
|
4953
|
+
INVALID_USER_ID: "INVALID_USER_ID",
|
|
4954
|
+
/** `organizationId` is not a UUID. */
|
|
4955
|
+
INVALID_ORGANIZATION_ID: "INVALID_ORGANIZATION_ID",
|
|
4956
|
+
/** A product claim uses a name the minter reserves (`sub`, `role`, `exp`, ...). */
|
|
4957
|
+
RESERVED_CLAIM: "RESERVED_CLAIM",
|
|
4958
|
+
/** `now` is not a valid `Date` (an Invalid Date would sign `iat` / `exp` as null). */
|
|
4959
|
+
INVALID_CLOCK: "INVALID_CLOCK"
|
|
4960
|
+
};
|
|
4961
|
+
var FFIDDbTokenError = class extends Error {
|
|
4962
|
+
code;
|
|
4963
|
+
constructor(code, message, options) {
|
|
4964
|
+
super(message, options);
|
|
4965
|
+
this.name = "FFIDDbTokenError";
|
|
4966
|
+
this.code = code;
|
|
4967
|
+
}
|
|
4968
|
+
};
|
|
4969
|
+
|
|
4970
|
+
// src/server/db-token/mint.ts
|
|
4971
|
+
var UUID_PATTERN2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
4972
|
+
var RESERVED_CLAIM_SET = new Set(FFID_DB_TOKEN_RESERVED_CLAIMS);
|
|
4973
|
+
var isNonEmptyString = (value) => typeof value === "string" && value.length > 0;
|
|
4974
|
+
var invalidKey = (reason, cause) => new FFIDDbTokenError(
|
|
4975
|
+
FFID_DB_TOKEN_ERROR_CODES.INVALID_SIGNING_KEY,
|
|
4976
|
+
`Invalid DB token signing key: ${reason}`,
|
|
4977
|
+
cause === void 0 ? void 0 : { cause }
|
|
4978
|
+
);
|
|
4979
|
+
var describeCause = (cause) => cause instanceof Error ? `${cause.name}: ${cause.message}` : String(cause);
|
|
4980
|
+
function parseSigningKey(signingKey, kidOverride) {
|
|
4981
|
+
let candidate = signingKey;
|
|
4982
|
+
if (typeof signingKey === "string") {
|
|
4983
|
+
if (signingKey.trim().length === 0) {
|
|
4984
|
+
throw invalidKey("signingKey is empty (is the environment variable set?)");
|
|
4985
|
+
}
|
|
4986
|
+
try {
|
|
4987
|
+
candidate = JSON.parse(signingKey);
|
|
4988
|
+
} catch {
|
|
4989
|
+
throw invalidKey("not valid JSON");
|
|
4990
|
+
}
|
|
4991
|
+
}
|
|
4992
|
+
if (typeof candidate !== "object" || candidate === null || Array.isArray(candidate)) {
|
|
4993
|
+
throw invalidKey("expected a JWK object");
|
|
4994
|
+
}
|
|
4995
|
+
const jwk = candidate;
|
|
4996
|
+
if (jwk.kty !== "EC" || jwk.crv !== "P-256") {
|
|
4997
|
+
throw invalidKey(`expected kty=EC crv=P-256 for ${FFID_DB_TOKEN_ALGORITHM}`);
|
|
4998
|
+
}
|
|
4999
|
+
if (!isNonEmptyString(jwk.d) || !isNonEmptyString(jwk.x) || !isNonEmptyString(jwk.y)) {
|
|
5000
|
+
throw invalidKey("expected a private key (d, x, y)");
|
|
5001
|
+
}
|
|
5002
|
+
const kid = kidOverride ?? jwk.kid;
|
|
5003
|
+
if (!isNonEmptyString(kid)) {
|
|
5004
|
+
throw invalidKey("kid is required (Supabase matches the header kid against the imported key)");
|
|
5005
|
+
}
|
|
5006
|
+
return { jwk, kid };
|
|
5007
|
+
}
|
|
5008
|
+
function resolveTtlSeconds(ttlSeconds) {
|
|
5009
|
+
const ttl = ttlSeconds ?? DEFAULT_DB_TOKEN_TTL_SECONDS;
|
|
5010
|
+
if (!Number.isInteger(ttl) || ttl < 1 || ttl > MAX_DB_TOKEN_TTL_SECONDS) {
|
|
5011
|
+
throw new FFIDDbTokenError(
|
|
5012
|
+
FFID_DB_TOKEN_ERROR_CODES.INVALID_TTL,
|
|
5013
|
+
`ttlSeconds must be an integer between 1 and ${MAX_DB_TOKEN_TTL_SECONDS}`
|
|
5014
|
+
);
|
|
5015
|
+
}
|
|
5016
|
+
return ttl;
|
|
5017
|
+
}
|
|
5018
|
+
function requireUuid(value, code, label) {
|
|
5019
|
+
if (typeof value !== "string" || !UUID_PATTERN2.test(value)) {
|
|
5020
|
+
throw new FFIDDbTokenError(FFID_DB_TOKEN_ERROR_CODES[code], `${label} must be a UUID`);
|
|
5021
|
+
}
|
|
5022
|
+
return value.toLowerCase();
|
|
5023
|
+
}
|
|
5024
|
+
function resolveNow(now) {
|
|
5025
|
+
if (now === void 0) return /* @__PURE__ */ new Date();
|
|
5026
|
+
if (!(now instanceof Date) || Number.isNaN(now.getTime())) {
|
|
5027
|
+
throw new FFIDDbTokenError(FFID_DB_TOKEN_ERROR_CODES.INVALID_CLOCK, "now must be a valid Date");
|
|
5028
|
+
}
|
|
5029
|
+
return now;
|
|
5030
|
+
}
|
|
5031
|
+
function assertNoReservedClaims(claims) {
|
|
5032
|
+
if (!claims) return;
|
|
5033
|
+
for (const name of Object.keys(claims)) {
|
|
5034
|
+
if (RESERVED_CLAIM_SET.has(name)) {
|
|
5035
|
+
throw new FFIDDbTokenError(
|
|
5036
|
+
FFID_DB_TOKEN_ERROR_CODES.RESERVED_CLAIM,
|
|
5037
|
+
`Claim "${name}" is reserved by the DB token minter`
|
|
5038
|
+
);
|
|
5039
|
+
}
|
|
5040
|
+
}
|
|
5041
|
+
}
|
|
5042
|
+
async function importSigningKey(jwk, kid) {
|
|
5043
|
+
const ecParameters = { kty: jwk.kty, crv: jwk.crv, x: jwk.x, y: jwk.y };
|
|
5044
|
+
let privateKey;
|
|
5045
|
+
let publicKey;
|
|
5046
|
+
try {
|
|
5047
|
+
const imported = await Promise.all([
|
|
5048
|
+
jose.importJWK({ ...ecParameters, d: jwk.d, kid, alg: FFID_DB_TOKEN_ALGORITHM }, FFID_DB_TOKEN_ALGORITHM),
|
|
5049
|
+
jose.importJWK({ ...ecParameters, kid, alg: FFID_DB_TOKEN_ALGORITHM }, FFID_DB_TOKEN_ALGORITHM)
|
|
5050
|
+
]);
|
|
5051
|
+
if (imported[0] instanceof Uint8Array || imported[1] instanceof Uint8Array) {
|
|
5052
|
+
throw new Error("expected an asymmetric key");
|
|
5053
|
+
}
|
|
5054
|
+
;
|
|
5055
|
+
[privateKey, publicKey] = imported;
|
|
5056
|
+
} catch (cause) {
|
|
5057
|
+
throw invalidKey(`key material could not be imported (${describeCause(cause)})`, cause);
|
|
5058
|
+
}
|
|
5059
|
+
try {
|
|
5060
|
+
const probe = await new jose.SignJWT({}).setProtectedHeader({ alg: FFID_DB_TOKEN_ALGORITHM, kid }).sign(privateKey);
|
|
5061
|
+
await jose.jwtVerify(probe, publicKey);
|
|
5062
|
+
} catch (cause) {
|
|
5063
|
+
throw invalidKey("private part (d) does not match the public part (x, y)", cause);
|
|
5064
|
+
}
|
|
5065
|
+
return privateKey;
|
|
5066
|
+
}
|
|
5067
|
+
function createDbTokenMinter(config) {
|
|
5068
|
+
const { jwk, kid } = parseSigningKey(config.signingKey, config.kid);
|
|
5069
|
+
const ttlSeconds = resolveTtlSeconds(config.ttlSeconds);
|
|
5070
|
+
const issuer = config.issuer;
|
|
5071
|
+
let keyPromise;
|
|
5072
|
+
const loadKey = () => {
|
|
5073
|
+
keyPromise ??= importSigningKey(jwk, kid).catch((error) => {
|
|
5074
|
+
keyPromise = void 0;
|
|
5075
|
+
throw error;
|
|
5076
|
+
});
|
|
5077
|
+
return keyPromise;
|
|
5078
|
+
};
|
|
5079
|
+
return {
|
|
5080
|
+
kid,
|
|
5081
|
+
ttlSeconds,
|
|
5082
|
+
async mint(input) {
|
|
5083
|
+
const sub = requireUuid(input.userId, "INVALID_USER_ID", "userId");
|
|
5084
|
+
const organizationId = input.organizationId === void 0 || input.organizationId === null ? void 0 : requireUuid(input.organizationId, "INVALID_ORGANIZATION_ID", "organizationId");
|
|
5085
|
+
assertNoReservedClaims(input.claims);
|
|
5086
|
+
const now = resolveNow(input.now);
|
|
5087
|
+
const iat = Math.floor(now.getTime() / MILLISECONDS_PER_SECOND);
|
|
5088
|
+
const exp = iat + ttlSeconds;
|
|
5089
|
+
const claims = {
|
|
5090
|
+
...input.claims,
|
|
5091
|
+
sub,
|
|
5092
|
+
role: FFID_DB_TOKEN_ROLE,
|
|
5093
|
+
aud: FFID_DB_TOKEN_AUDIENCE,
|
|
5094
|
+
iat,
|
|
5095
|
+
exp,
|
|
5096
|
+
...issuer === void 0 ? {} : { iss: issuer },
|
|
5097
|
+
...organizationId === void 0 ? {} : { [FFID_DB_TOKEN_ORGANIZATION_CLAIM]: organizationId }
|
|
5098
|
+
};
|
|
5099
|
+
const key = await loadKey();
|
|
5100
|
+
const token = await new jose.SignJWT(claims).setProtectedHeader({ alg: FFID_DB_TOKEN_ALGORITHM, kid, typ: "JWT" }).sign(key);
|
|
5101
|
+
return { token, expiresAt: new Date(exp * MILLISECONDS_PER_SECOND), claims };
|
|
5102
|
+
}
|
|
5103
|
+
};
|
|
5104
|
+
}
|
|
5105
|
+
|
|
4868
5106
|
Object.defineProperty(exports, "DEFAULT_API_BASE_URL", {
|
|
4869
5107
|
enumerable: true,
|
|
4870
5108
|
get: function () { return chunkMDHKSVLP_cjs.DEFAULT_API_BASE_URL; }
|
|
@@ -4877,11 +5115,19 @@ exports.ALL_DENIED_EXCEPT_NECESSARY = ALL_DENIED_EXCEPT_NECESSARY;
|
|
|
4877
5115
|
exports.CATALOG_HASH_PATTERN = CATALOG_HASH_PATTERN;
|
|
4878
5116
|
exports.CONSENT_COOKIE_NAME = CONSENT_COOKIE_NAME;
|
|
4879
5117
|
exports.COOKIE_VERSION = COOKIE_VERSION;
|
|
5118
|
+
exports.DEFAULT_DB_TOKEN_TTL_SECONDS = DEFAULT_DB_TOKEN_TTL_SECONDS;
|
|
4880
5119
|
exports.FFIDCatalogHashError = FFIDCatalogHashError;
|
|
5120
|
+
exports.FFIDDbTokenError = FFIDDbTokenError;
|
|
4881
5121
|
exports.FFID_ALLOWED_ORGANIZATION_LOGO_MIME_TYPES = FFID_ALLOWED_ORGANIZATION_LOGO_MIME_TYPES;
|
|
4882
5122
|
exports.FFID_CATALOG_ENVIRONMENTS = FFID_CATALOG_ENVIRONMENTS;
|
|
4883
5123
|
exports.FFID_CATALOG_PUBLICATION_STATUSES = FFID_CATALOG_PUBLICATION_STATUSES;
|
|
4884
5124
|
exports.FFID_COMPANY_SIZE_CODES = FFID_COMPANY_SIZE_CODES;
|
|
5125
|
+
exports.FFID_DB_TOKEN_ALGORITHM = FFID_DB_TOKEN_ALGORITHM;
|
|
5126
|
+
exports.FFID_DB_TOKEN_AUDIENCE = FFID_DB_TOKEN_AUDIENCE;
|
|
5127
|
+
exports.FFID_DB_TOKEN_ERROR_CODES = FFID_DB_TOKEN_ERROR_CODES;
|
|
5128
|
+
exports.FFID_DB_TOKEN_ORGANIZATION_CLAIM = FFID_DB_TOKEN_ORGANIZATION_CLAIM;
|
|
5129
|
+
exports.FFID_DB_TOKEN_RESERVED_CLAIMS = FFID_DB_TOKEN_RESERVED_CLAIMS;
|
|
5130
|
+
exports.FFID_DB_TOKEN_ROLE = FFID_DB_TOKEN_ROLE;
|
|
4885
5131
|
exports.FFID_ERROR_CODES = FFID_ERROR_CODES;
|
|
4886
5132
|
exports.FFID_INDUSTRY_CODES = FFID_INDUSTRY_CODES;
|
|
4887
5133
|
exports.FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES = FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES;
|
|
@@ -4889,6 +5135,7 @@ exports.FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB = FFID_MAX_ORGANIZATION_LOGO_FIL
|
|
|
4889
5135
|
exports.FFID_OAUTH_DENIAL_REASONS = FFID_OAUTH_DENIAL_REASONS;
|
|
4890
5136
|
exports.FFID_ORGANIZATION_PROFILE_ERROR_CODES = FFID_ORGANIZATION_PROFILE_ERROR_CODES;
|
|
4891
5137
|
exports.FFID_SESSION_COOKIE_NAME = FFID_SESSION_COOKIE_NAME;
|
|
5138
|
+
exports.MAX_DB_TOKEN_TTL_SECONDS = MAX_DB_TOKEN_TTL_SECONDS;
|
|
4892
5139
|
exports.canonicalizeCatalogValue = canonicalizeCatalogValue;
|
|
4893
5140
|
exports.computeFFIDCheckoutCopyHash = computeFFIDCheckoutCopyHash;
|
|
4894
5141
|
exports.computeLegalDisclosureHash = computeLegalDisclosureHash;
|
|
@@ -4896,6 +5143,7 @@ exports.computePaymentConfigurationHash = computePaymentConfigurationHash;
|
|
|
4896
5143
|
exports.computePraxisCopyHash = computePraxisCopyHash;
|
|
4897
5144
|
exports.computeScopeHash = computeScopeHash;
|
|
4898
5145
|
exports.computeTaxConfigurationHash = computeTaxConfigurationHash;
|
|
5146
|
+
exports.createDbTokenMinter = createDbTokenMinter;
|
|
4899
5147
|
exports.createFFIDClient = createFFIDClient;
|
|
4900
5148
|
exports.createKVCacheAdapter = createKVCacheAdapter;
|
|
4901
5149
|
exports.createMemoryCacheAdapter = createMemoryCacheAdapter;
|
package/dist/server/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FFIDError, a as FFIDLogger, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo, f as FFIDCatalogEnvironment, g as FFIDBillingInterval, h as FFIDTaxBehavior, i as FFIDPublishedCatalog } from '../ffid-client-
|
|
2
|
-
export { j as FFIDAddMemberParams, k as FFIDAddMemberRequest, l as FFIDAddMemberResponse, m as FFIDAllowedLogoMimeType, n as FFIDAssignableMemberRole, o as FFIDCacheConfig, p as FFIDCatalogPublication, q as FFIDCatalogPublicationStatus, r as FFIDClient, s as FFIDCompanySizeCode, t as FFIDConfig, u as FFIDIndustryCode, v as FFIDListMembersResponse, w as FFIDListingConsentInput, x as FFIDLogoWallEntry, y as FFIDLogoWallResponse, z as FFIDMemberRole, A as FFIDMemberSeatAssignmentResult, B as FFIDOrganization, C as FFIDOrganizationLogoUploadResponse, D as FFIDOrganizationMember, E as FFIDOrganizationProfile, G as FFIDOrganizationProfileErrorCode, H as FFIDOrganizationProfileResponse, I as FFIDOtpSendResponse, J as FFIDOtpVerifyResponse, K as FFIDPasswordResetConfirmResponse, L as FFIDPasswordResetResponse, M as FFIDPasswordResetVerifyResponse, N as FFIDProfileCallOptions, O as FFIDProvisionMemberPlan, P as FFIDProvisionMemberPlanStatus, Q as FFIDProvisionMemberResult, R as FFIDProvisionMemberStatus, S as FFIDProvisionOrganizationDryRun, T as FFIDProvisionOrganizationMemberInput, U as FFIDProvisionOrganizationOutcome, V as FFIDProvisionOrganizationParams, W as FFIDProvisionOrganizationResponse, X as FFIDProvisionUserDryRun, Y as FFIDProvisionUserOutcome, Z as FFIDProvisionUserParams, _ as FFIDProvisionUserProfileInput, $ as FFIDProvisionUserResponse, a0 as FFIDProvisionedOrganization, a1 as FFIDProvisionedUser, a2 as FFIDPublishedPlan, a3 as FFIDRemoveMemberResponse, a4 as FFIDResetSessionResponse, a5 as FFIDSubscription, a6 as FFIDUpdateMemberRoleResponse, a7 as FFIDUpdateUserProfileRequest, a8 as FFIDUploadOrganizationLogoParams, a9 as FFIDUpsertOrganizationProfileParams, aa as FFIDUpsertOrganizationProfileRequest, ab as FFIDUser, ac as FFIDUserProfile, ad as FFID_ALLOWED_ORGANIZATION_LOGO_MIME_TYPES, ae as FFID_CATALOG_ENVIRONMENTS, af as FFID_CATALOG_PUBLICATION_STATUSES, ag as FFID_COMPANY_SIZE_CODES, ah as FFID_INDUSTRY_CODES, ai as FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES, aj as FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB, ak as FFID_ORGANIZATION_PROFILE_ERROR_CODES, al as TokenData, am as TokenStore, an as createFFIDClient, ao as createTokenStore } from '../ffid-client-
|
|
1
|
+
import { F as FFIDError, a as FFIDLogger, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo, f as FFIDCatalogEnvironment, g as FFIDBillingInterval, h as FFIDTaxBehavior, i as FFIDPublishedCatalog } from '../ffid-client-DMwmK8mM.cjs';
|
|
2
|
+
export { j as FFIDAddMemberParams, k as FFIDAddMemberRequest, l as FFIDAddMemberResponse, m as FFIDAllowedLogoMimeType, n as FFIDAssignableMemberRole, o as FFIDCacheConfig, p as FFIDCatalogPublication, q as FFIDCatalogPublicationStatus, r as FFIDClient, s as FFIDCompanySizeCode, t as FFIDConfig, u as FFIDIndustryCode, v as FFIDListMembersResponse, w as FFIDListingConsentInput, x as FFIDLogoWallEntry, y as FFIDLogoWallResponse, z as FFIDMemberRole, A as FFIDMemberSeatAssignmentResult, B as FFIDOrganization, C as FFIDOrganizationLogoUploadResponse, D as FFIDOrganizationMember, E as FFIDOrganizationProfile, G as FFIDOrganizationProfileErrorCode, H as FFIDOrganizationProfileResponse, I as FFIDOtpSendResponse, J as FFIDOtpVerifyResponse, K as FFIDPasswordResetConfirmResponse, L as FFIDPasswordResetResponse, M as FFIDPasswordResetVerifyResponse, N as FFIDProfileCallOptions, O as FFIDProvisionMemberPlan, P as FFIDProvisionMemberPlanStatus, Q as FFIDProvisionMemberResult, R as FFIDProvisionMemberStatus, S as FFIDProvisionOrganizationDryRun, T as FFIDProvisionOrganizationMemberInput, U as FFIDProvisionOrganizationOutcome, V as FFIDProvisionOrganizationParams, W as FFIDProvisionOrganizationResponse, X as FFIDProvisionUserDryRun, Y as FFIDProvisionUserOutcome, Z as FFIDProvisionUserParams, _ as FFIDProvisionUserProfileInput, $ as FFIDProvisionUserResponse, a0 as FFIDProvisionedOrganization, a1 as FFIDProvisionedUser, a2 as FFIDPublishedPlan, a3 as FFIDRemoveMemberResponse, a4 as FFIDResetSessionResponse, a5 as FFIDSubscription, a6 as FFIDUpdateMemberRoleResponse, a7 as FFIDUpdateUserProfileRequest, a8 as FFIDUploadOrganizationLogoParams, a9 as FFIDUpsertOrganizationProfileParams, aa as FFIDUpsertOrganizationProfileRequest, ab as FFIDUser, ac as FFIDUserProfile, ad as FFID_ALLOWED_ORGANIZATION_LOGO_MIME_TYPES, ae as FFID_CATALOG_ENVIRONMENTS, af as FFID_CATALOG_PUBLICATION_STATUSES, ag as FFID_COMPANY_SIZE_CODES, ah as FFID_INDUSTRY_CODES, ai as FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES, aj as FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB, ak as FFID_ORGANIZATION_PROFILE_ERROR_CODES, al as TokenData, am as TokenStore, an as createFFIDClient, ao as createTokenStore } from '../ffid-client-DMwmK8mM.cjs';
|
|
3
3
|
export { D as DEFAULT_API_BASE_URL, a as DEFAULT_OAUTH_SCOPES } from '../constants-Ce2eXQtB.cjs';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import '../types-Cjb9J0rL.cjs';
|
|
@@ -649,4 +649,147 @@ declare function computeScopeHash(input: FFIDScopeHashInput): Promise<string>;
|
|
|
649
649
|
*/
|
|
650
650
|
declare function validatePublishedCatalog(catalog: unknown): asserts catalog is FFIDPublishedCatalog;
|
|
651
651
|
|
|
652
|
-
|
|
652
|
+
/**
|
|
653
|
+
* Constants for the product-side DB token minter (#6318).
|
|
654
|
+
*
|
|
655
|
+
* A product that reaches its own Supabase through supabase-js (PostgREST)
|
|
656
|
+
* mints a short-lived token for the FFID user on its server and sends it as
|
|
657
|
+
* the `Authorization: Bearer` header. Supabase validates it against the
|
|
658
|
+
* product's JWT Signing Keys and RLS reads the user from `auth.jwt()`.
|
|
659
|
+
*/
|
|
660
|
+
/** Only asymmetric signing is allowed; a shared secret (HS256) is rejected by policy. */
|
|
661
|
+
declare const FFID_DB_TOKEN_ALGORITHM: "ES256";
|
|
662
|
+
/** Supabase maps this claim to the Postgres role the request runs as. */
|
|
663
|
+
declare const FFID_DB_TOKEN_ROLE: "authenticated";
|
|
664
|
+
/** Same shape as the user tokens Supabase Auth issues (`aud` = `authenticated`). */
|
|
665
|
+
declare const FFID_DB_TOKEN_AUDIENCE: "authenticated";
|
|
666
|
+
/** Default lifetime: 5 minutes. The token is minted per request and never sent to the browser. */
|
|
667
|
+
declare const DEFAULT_DB_TOKEN_TTL_SECONDS = 300;
|
|
668
|
+
/** Hard ceiling: 15 minutes. Longer tokens defeat the "mint per request" model. */
|
|
669
|
+
declare const MAX_DB_TOKEN_TTL_SECONDS = 900;
|
|
670
|
+
/** Claim that carries the FFID organization id when the product scopes rows by organization. */
|
|
671
|
+
declare const FFID_DB_TOKEN_ORGANIZATION_CLAIM: "organization_id";
|
|
672
|
+
/**
|
|
673
|
+
* Claims the minter owns. Product-specific `claims` must not use these names,
|
|
674
|
+
* so a caller cannot forge a different user, role, or lifetime.
|
|
675
|
+
*/
|
|
676
|
+
declare const FFID_DB_TOKEN_RESERVED_CLAIMS: readonly ["sub", "role", "aud", "iss", "iat", "exp", "nbf", "jti", "organization_id"];
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Types for the product-side DB token minter (#6318).
|
|
680
|
+
*/
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* Private P-256 JWK used to sign DB tokens. Generate it with
|
|
684
|
+
* `supabase gen signing-key --algorithm ES256`, import that private JWK into the
|
|
685
|
+
* product's Supabase JWT Signing Keys (Supabase keeps it non-extractable and
|
|
686
|
+
* publishes only the public half via JWKS), and keep the same JWK in a server
|
|
687
|
+
* environment variable. Nothing else may hold it.
|
|
688
|
+
*
|
|
689
|
+
* The CLI output also carries `use`, `key_ops` and `ext`; the minter strips
|
|
690
|
+
* those before import (WebCrypto rejects an ECDSA private key whose `key_ops`
|
|
691
|
+
* includes `verify`).
|
|
692
|
+
*/
|
|
693
|
+
interface FFIDDbTokenSigningJwk {
|
|
694
|
+
kty: 'EC';
|
|
695
|
+
crv: 'P-256';
|
|
696
|
+
/** Private scalar. Its presence is what makes this a signing key. */
|
|
697
|
+
d: string;
|
|
698
|
+
x: string;
|
|
699
|
+
y: string;
|
|
700
|
+
/** Key id. Supabase matches the token header `kid` against the imported key. */
|
|
701
|
+
kid?: string;
|
|
702
|
+
alg?: string;
|
|
703
|
+
use?: string;
|
|
704
|
+
[parameter: string]: unknown;
|
|
705
|
+
}
|
|
706
|
+
interface FFIDDbTokenMinterConfig {
|
|
707
|
+
/**
|
|
708
|
+
* The private JWK, either as an object or as the JSON string stored in an
|
|
709
|
+
* environment variable (for example `SUPABASE_JWT_SIGNING_KEY`).
|
|
710
|
+
*/
|
|
711
|
+
signingKey: string | FFIDDbTokenSigningJwk;
|
|
712
|
+
/** Overrides the JWK's `kid`. Required when the JWK has none. */
|
|
713
|
+
kid?: string;
|
|
714
|
+
/** Token lifetime. Default `DEFAULT_DB_TOKEN_TTL_SECONDS`, max `MAX_DB_TOKEN_TTL_SECONDS`. */
|
|
715
|
+
ttlSeconds?: number;
|
|
716
|
+
/** Optional `iss` claim. Supabase does not require it; set it when the product's policies read it. */
|
|
717
|
+
issuer?: string;
|
|
718
|
+
}
|
|
719
|
+
interface FFIDMintDbTokenInput {
|
|
720
|
+
/** FFID user id (UUID). Becomes `sub`, the value `private.current_ffid_user_id()` returns. */
|
|
721
|
+
userId: string;
|
|
722
|
+
/** FFID organization id (UUID). Becomes the `organization_id` claim. `null` means "none", like `FFIDUser.organizationId`. */
|
|
723
|
+
organizationId?: string | null;
|
|
724
|
+
/** Product-specific claims. Reserved names (`FFID_DB_TOKEN_RESERVED_CLAIMS`) are rejected. */
|
|
725
|
+
claims?: Record<string, unknown>;
|
|
726
|
+
/** Clock override for tests. Defaults to `new Date()`. An Invalid Date is rejected (`INVALID_CLOCK`). */
|
|
727
|
+
now?: Date;
|
|
728
|
+
}
|
|
729
|
+
interface FFIDDbTokenClaims {
|
|
730
|
+
sub: string;
|
|
731
|
+
role: typeof FFID_DB_TOKEN_ROLE;
|
|
732
|
+
aud: typeof FFID_DB_TOKEN_AUDIENCE;
|
|
733
|
+
iat: number;
|
|
734
|
+
exp: number;
|
|
735
|
+
iss?: string;
|
|
736
|
+
organization_id?: string;
|
|
737
|
+
[claim: string]: unknown;
|
|
738
|
+
}
|
|
739
|
+
interface FFIDDbToken {
|
|
740
|
+
/** Compact JWS to send as `Authorization: Bearer <token>` to the product's Supabase. */
|
|
741
|
+
token: string;
|
|
742
|
+
/** `exp` as a `Date`. For logging / diagnostics; the client is still created per request. */
|
|
743
|
+
expiresAt: Date;
|
|
744
|
+
/** The signed payload, for logging claim names (never log the token itself). */
|
|
745
|
+
claims: FFIDDbTokenClaims;
|
|
746
|
+
}
|
|
747
|
+
interface FFIDDbTokenMinter {
|
|
748
|
+
/** Key id written to every token header. */
|
|
749
|
+
readonly kid: string;
|
|
750
|
+
/** Effective lifetime in seconds. */
|
|
751
|
+
readonly ttlSeconds: number;
|
|
752
|
+
mint(input: FFIDMintDbTokenInput): Promise<FFIDDbToken>;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
/**
|
|
756
|
+
* Creates a minter bound to one signing key. Create it once per process and
|
|
757
|
+
* call `mint()` per request.
|
|
758
|
+
*
|
|
759
|
+
* The key shape is checked synchronously here. The key material is imported on
|
|
760
|
+
* the first `mint()`; a successful import is kept for the minter's lifetime,
|
|
761
|
+
* a failed one is retried on the next `mint()`.
|
|
762
|
+
*
|
|
763
|
+
* @throws FFIDDbTokenError when the key shape or TTL is invalid.
|
|
764
|
+
*/
|
|
765
|
+
declare function createDbTokenMinter(config: FFIDDbTokenMinterConfig): FFIDDbTokenMinter;
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Errors thrown by the product-side DB token minter (#6318).
|
|
769
|
+
*
|
|
770
|
+
* These are programming / configuration errors on the product's server, never
|
|
771
|
+
* end-user input errors. Messages never include key material.
|
|
772
|
+
*/
|
|
773
|
+
declare const FFID_DB_TOKEN_ERROR_CODES: {
|
|
774
|
+
/** Signing key is not a private P-256 JWK with a `kid`, or cannot be imported. */
|
|
775
|
+
readonly INVALID_SIGNING_KEY: "INVALID_SIGNING_KEY";
|
|
776
|
+
/** `ttlSeconds` is not a positive integer within `MAX_DB_TOKEN_TTL_SECONDS`. */
|
|
777
|
+
readonly INVALID_TTL: "INVALID_TTL";
|
|
778
|
+
/** `userId` is not a UUID. */
|
|
779
|
+
readonly INVALID_USER_ID: "INVALID_USER_ID";
|
|
780
|
+
/** `organizationId` is not a UUID. */
|
|
781
|
+
readonly INVALID_ORGANIZATION_ID: "INVALID_ORGANIZATION_ID";
|
|
782
|
+
/** A product claim uses a name the minter reserves (`sub`, `role`, `exp`, ...). */
|
|
783
|
+
readonly RESERVED_CLAIM: "RESERVED_CLAIM";
|
|
784
|
+
/** `now` is not a valid `Date` (an Invalid Date would sign `iat` / `exp` as null). */
|
|
785
|
+
readonly INVALID_CLOCK: "INVALID_CLOCK";
|
|
786
|
+
};
|
|
787
|
+
type FFIDDbTokenErrorCode = (typeof FFID_DB_TOKEN_ERROR_CODES)[keyof typeof FFID_DB_TOKEN_ERROR_CODES];
|
|
788
|
+
declare class FFIDDbTokenError extends Error {
|
|
789
|
+
readonly code: FFIDDbTokenErrorCode;
|
|
790
|
+
constructor(code: FFIDDbTokenErrorCode, message: string, options?: {
|
|
791
|
+
cause?: unknown;
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
export { ALL_DENIED_EXCEPT_NECESSARY, type BuildAuthorizeUrlOptions, type BuildAuthorizeUrlResult, CATALOG_HASH_PATTERN, CONSENT_COOKIE_NAME, COOKIE_VERSION, type CookieOptions, DEFAULT_DB_TOKEN_TTL_SECONDS, type FFIDAuthorizationError, type FFIDAuthorizationErrorDetails, FFIDCacheAdapter, type FFIDCanonicalJsonValue, FFIDCatalogEnvironment, FFIDCatalogHashError, type FFIDConsentCategories, type FFIDConsentCategoryCode, type FFIDCookieStoreLike, type FFIDDbToken, type FFIDDbTokenClaims, FFIDDbTokenError, type FFIDDbTokenErrorCode, type FFIDDbTokenMinter, type FFIDDbTokenMinterConfig, type FFIDDbTokenSigningJwk, type FFIDErrorCode, type FFIDMintDbTokenInput, type FFIDOAuthDenialReason, FFIDOAuthUserInfo, type FFIDPaymentConfiguration, FFIDPublishedCatalog, type FFIDScopeHashInput, type FFIDScopeHashPlan, FFIDTaxBehavior, type FFIDTaxConfiguration, FFIDVerifyAccessTokenOptions, FFID_DB_TOKEN_ALGORITHM, FFID_DB_TOKEN_AUDIENCE, FFID_DB_TOKEN_ERROR_CODES, FFID_DB_TOKEN_ORGANIZATION_CLAIM, FFID_DB_TOKEN_RESERVED_CLAIMS, FFID_DB_TOKEN_ROLE, FFID_ERROR_CODES, FFID_OAUTH_DENIAL_REASONS, FFID_SESSION_COOKIE_NAME, type HandleCallbackInput, type KVNamespaceLike, MAX_DB_TOKEN_TTL_SECONDS, type ServerAuthClient, type ServerAuthConfig, type ServerSessionTokens, type ServerTokenResult, canonicalizeCatalogValue, computeFFIDCheckoutCopyHash, computeLegalDisclosureHash, computePaymentConfigurationHash, computePraxisCopyHash, computeScopeHash, computeTaxConfigurationHash, createDbTokenMinter, createKVCacheAdapter, createMemoryCacheAdapter, createServerAuthClient, createVerifyAccessToken, decodeConsentCookie, encodeConsentCookie, generateServerState, getFFIDAuthorizationError, getFFIDConsentFromCookieHeader, getFFIDConsentFromCookies, hashCanonicalJson, isFFIDOAuthDenialReason, sessionCookies, sha256Hex, validatePublishedCatalog };
|