kavachos 0.0.3 → 0.0.5
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/dist/a2a/index.d.ts +2341 -0
- package/dist/a2a/index.js +821 -0
- package/dist/a2a/index.js.map +1 -0
- package/dist/agent/index.d.ts +3 -3
- package/dist/agent/index.js +3 -2
- package/dist/audit/index.d.ts +2 -2
- package/dist/audit/index.js +2 -2
- package/dist/auth/index.d.ts +490 -92
- package/dist/auth/index.js +3 -2
- package/dist/chunk-3AZDFCQF.js +186 -0
- package/dist/chunk-3AZDFCQF.js.map +1 -0
- package/dist/{chunk-SJGSPIAD.js → chunk-4CANWZWP.js} +3 -3
- package/dist/{chunk-SJGSPIAD.js.map → chunk-4CANWZWP.js.map} +1 -1
- package/dist/{chunk-KL6XW4S4.js → chunk-62P5FJ34.js} +2375 -633
- package/dist/chunk-62P5FJ34.js.map +1 -0
- package/dist/chunk-ELGG2VW2.js +538 -0
- package/dist/chunk-ELGG2VW2.js.map +1 -0
- package/dist/{chunk-5DT4DN4Y.js → chunk-IS5FRKIS.js} +13 -13
- package/dist/chunk-IS5FRKIS.js.map +1 -0
- package/dist/{chunk-V66UUIA7.js → chunk-KNNJ4COO.js} +92 -3
- package/dist/chunk-KNNJ4COO.js.map +1 -0
- package/dist/{chunk-OVGNZ5OX.js → chunk-O7VQ2LQE.js} +6 -6
- package/dist/chunk-O7VQ2LQE.js.map +1 -0
- package/dist/index.d.ts +138 -5
- package/dist/index.js +564 -29
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.d.ts +2 -2
- package/dist/mcp/index.js +11 -15
- package/dist/mcp/index.js.map +1 -1
- package/dist/permission/index.d.ts +3 -3
- package/dist/permission/index.js +3 -2
- package/dist/{types-Xk83hv4O.d.ts → types-BTui0HQU.d.ts} +1763 -98
- package/dist/vc/index.d.ts +800 -0
- package/dist/vc/index.js +5 -0
- package/dist/vc/index.js.map +1 -0
- package/package.json +17 -1
- package/dist/chunk-5DT4DN4Y.js.map +0 -1
- package/dist/chunk-KL6XW4S4.js.map +0 -1
- package/dist/chunk-OVGNZ5OX.js.map +0 -1
- package/dist/chunk-V66UUIA7.js.map +0 -1
- package/dist/{types-mwupB57A.d.ts → types-BuHrZcjE.d.ts} +2 -2
package/dist/index.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import { createAgentModule } from './chunk-
|
|
2
|
-
export { createAgentModule } from './chunk-
|
|
3
|
-
import { createSessionManager, createMagicLinkModule, createEmailOtpModule, createTotpModule, createPasskeyModule, createOrgModule, createSsoModule, createAdminModule, createApiKeyManagerModule, createUsernameAuthModule, createPhoneAuthModule, createCaptchaModule, createWebhookModule } from './chunk-
|
|
4
|
-
export { HibpApiError, HibpBreachedError, OAuthProxyError, OneTapVerifyError, SSO_ERROR, SsoError, additionalFields, admin, anonymousAuth, apiKeys, bearerAuth, createAdditionalFieldsModule, createAdminModule, createAnonymousAuthModule, createApiKeyManagerModule, createCaptchaModule, createCustomSessionModule, createDeviceAuthModule, createEmailOtpModule, createGdprModule, createHibpModule, createJwtSessionModule, createLastLoginModule, createMagicLinkModule, createOAuthProxyModule, createOidcProviderModule, createOneTapModule, createOneTimeTokenModule, createOpenApiModule, createOrgModule, createPasskeyModule, createPhoneAuthModule, createPolarModule, createRateLimiter, createScimModule, createSessionManager, createSiweModule, createSsoModule, createStripeModule, createTotpModule, createTrustedDeviceModule, createUsernameAuthModule, customAuth, customSession, deviceAuth, deviceLabelFromRequest, emailOtp, gdpr, headerAuth, magicLink, oauthProxy, oneTap, organization, passkey, polar, scim, siwe, stripe, twoFactor, withRateLimit } from './chunk-
|
|
5
|
-
import { createPermissionEngine } from './chunk-
|
|
6
|
-
export { createPermissionEngine, getPermissionTemplate, permissionTemplates } from './chunk-
|
|
7
|
-
import { createAuditModule } from './chunk-
|
|
8
|
-
export { createAuditModule } from './chunk-
|
|
9
|
-
import { schema_exports, approvalRequests, sessions, delegationChains, agentDids, mcpServers, budgetPolicies, agents, permissions, auditLogs, tenants, trustScores } from './chunk-
|
|
10
|
-
export { agentCards, agentDids, agents, apiKeys as apiKeysTable, approvalRequests, auditLogs, budgetPolicies, delegationChains, emailOtps, magicLinks, mcpServers, oauthAccessTokens, oauthAuthorizationCodes, oauthClients, orgInvitations, orgMembers, orgRoles, organizations, passkeyChallenges, passkeyCredentials, permissions, rateLimits, sessions, ssoConnections, tenants, totpRecords, trustScores, users } from './chunk-
|
|
1
|
+
import { createAgentModule } from './chunk-IS5FRKIS.js';
|
|
2
|
+
export { createAgentModule } from './chunk-IS5FRKIS.js';
|
|
3
|
+
import { createSessionManager, createMagicLinkModule, createEmailOtpModule, createTotpModule, createPasskeyModule, createOrgModule, createSsoModule, createAdminModule, createApiKeyManagerModule, createUsernameAuthModule, createOneTimeTokenModule, createPasswordResetModule, createEmailVerificationModule, createPhoneAuthModule, createCaptchaModule, createWebhookModule } from './chunk-62P5FJ34.js';
|
|
4
|
+
export { EVENT_TYPES, HibpApiError, HibpBreachedError, OAuthProxyError, OneTapVerifyError, SSO_ERROR, SsoError, additionalFields, admin, anonymousAuth, apiKeys, bearerAuth, createAdditionalFieldsModule, createAdminModule, createAnonymousAuthModule, createApiKeyManagerModule, createCaptchaModule, createCostAttributionModule, createCustomSessionModule, createDeviceAuthModule, createEmailOtpModule, createEmailVerificationModule, createEphemeralSessionModule, createEventStreamModule, createFederationModule, createGdprModule, createHibpModule, createJwtSessionModule, createLastLoginModule, createMagicLinkModule, createOAuthProxyModule, createOidcProviderModule, createOneTapModule, createOneTimeTokenModule, createOpenApiModule, createOrgModule, createPasskeyModule, createPasswordResetModule, createPhoneAuthModule, createPolarModule, createRateLimiter, createReBACModule, createScimModule, createSessionManager, createSiweModule, createSsoModule, createStripeModule, createTotpModule, createTrustedDeviceModule, createUsernameAuthModule, customAuth, customSession, deviceAuth, deviceLabelFromRequest, emailOtp, gdpr, headerAuth, magicLink, oauthProxy, oneTap, organization, passkey, polar, scim, siwe, stripe, twoFactor, withRateLimit } from './chunk-62P5FJ34.js';
|
|
5
|
+
import { createPermissionEngine } from './chunk-O7VQ2LQE.js';
|
|
6
|
+
export { createPermissionEngine, getPermissionTemplate, permissionTemplates } from './chunk-O7VQ2LQE.js';
|
|
7
|
+
import { createAuditModule } from './chunk-4CANWZWP.js';
|
|
8
|
+
export { createAuditModule } from './chunk-4CANWZWP.js';
|
|
9
|
+
import { schema_exports, approvalRequests, sessions, delegationChains, agentDids, mcpServers, budgetPolicies, agents, permissions, auditLogs, tenants, trustScores } from './chunk-KNNJ4COO.js';
|
|
10
|
+
export { agentCards, agentDids, agents, apiKeys as apiKeysTable, approvalRequests, auditLogs, budgetPolicies, delegationChains, emailOtps, magicLinks, mcpServers, oauthAccessTokens, oauthAuthorizationCodes, oauthClients, orgInvitations, orgMembers, orgRoles, organizations, passkeyChallenges, passkeyCredentials, permissions, rateLimits, sessions, ssoConnections, tenants, totpRecords, trustScores, users } from './chunk-KNNJ4COO.js';
|
|
11
|
+
export { CredentialStatusSchema, CredentialSubjectSchema, KAVACH_AGENT_CREDENTIAL, KAVACH_DELEGATION_CREDENTIAL, KAVACH_PERMISSION_CREDENTIAL, ProofSchema, VC_CONTEXT_V1, VC_CONTEXT_V2, VC_TYPE_CREDENTIAL, VC_TYPE_PRESENTATION, VerifiableCredentialSchema, VerifiablePresentationSchema, createVCIssuer, createVCVerifier } from './chunk-ELGG2VW2.js';
|
|
12
|
+
import { generateId } from './chunk-3AZDFCQF.js';
|
|
13
|
+
export { constantTimeEqual, fromBase64Url, fromHex, generateId, hmacSha1Raw, hmacSha256, hmacSha256Raw, importHmacKey, pbkdf2Hash, pbkdf2Verify, randomBytes, randomBytesHex, sha1, sha256, sha256Raw, toBase64Url, toHex } from './chunk-3AZDFCQF.js';
|
|
11
14
|
import './chunk-PZ5AY32C.js';
|
|
12
15
|
import { eq, and, lt, ne, or, isNull, gte } from 'drizzle-orm';
|
|
13
|
-
import { randomUUID } from 'crypto';
|
|
14
16
|
import BetterSqlite3 from 'better-sqlite3';
|
|
15
17
|
import { drizzle } from 'drizzle-orm/better-sqlite3';
|
|
16
18
|
import { generateKeyPair, exportJWK, importJWK, SignJWT, jwtVerify } from 'jose';
|
|
@@ -226,7 +228,7 @@ function createApprovalModule(config, db) {
|
|
|
226
228
|
const ttlSeconds = config.ttl ?? 300;
|
|
227
229
|
async function request(input) {
|
|
228
230
|
const now = /* @__PURE__ */ new Date();
|
|
229
|
-
const id = `apr_${
|
|
231
|
+
const id = `apr_${generateId()}`;
|
|
230
232
|
const expiresAt = new Date(now.getTime() + ttlSeconds * 1e3);
|
|
231
233
|
await db.insert(approvalRequests).values({
|
|
232
234
|
id,
|
|
@@ -341,8 +343,12 @@ async function createDatabase(config) {
|
|
|
341
343
|
const pool = mysql2.createPool(config.url);
|
|
342
344
|
return drizzle(pool);
|
|
343
345
|
}
|
|
346
|
+
if (config.provider === "d1") {
|
|
347
|
+
const { drizzle } = await import('drizzle-orm/d1');
|
|
348
|
+
return drizzle(config.binding, { schema: schema_exports });
|
|
349
|
+
}
|
|
344
350
|
throw new Error(
|
|
345
|
-
`KavachOS: unsupported database provider "${config.provider}". Valid values are "sqlite", "postgres", "mysql".`
|
|
351
|
+
`KavachOS: unsupported database provider "${config.provider}". Valid values are "sqlite", "postgres", "mysql", "d1".`
|
|
346
352
|
);
|
|
347
353
|
}
|
|
348
354
|
function createDatabaseSync(config) {
|
|
@@ -382,6 +388,7 @@ function buildStatements(provider) {
|
|
|
382
388
|
ban_reason TEXT,
|
|
383
389
|
ban_expires_at ${tsNull},
|
|
384
390
|
force_password_reset ${bool} NOT NULL DEFAULT ${isPostgres ? "FALSE" : "0"},
|
|
391
|
+
email_verified ${bool} NOT NULL DEFAULT ${isPostgres ? "FALSE" : "0"},
|
|
385
392
|
stripe_customer_id TEXT UNIQUE,
|
|
386
393
|
stripe_subscription_id TEXT,
|
|
387
394
|
stripe_subscription_status TEXT,
|
|
@@ -857,6 +864,45 @@ function buildStatements(provider) {
|
|
|
857
864
|
expires_at ${ts} NOT NULL,
|
|
858
865
|
created_at ${ts} NOT NULL
|
|
859
866
|
)`,
|
|
867
|
+
// ------------------------------------------------------------------
|
|
868
|
+
// kavach_cost_events (per-agent cost attribution)
|
|
869
|
+
// ------------------------------------------------------------------
|
|
870
|
+
`CREATE TABLE ${ifne} kavach_cost_events (
|
|
871
|
+
id TEXT NOT NULL PRIMARY KEY,
|
|
872
|
+
agent_id TEXT NOT NULL REFERENCES kavach_agents(id) ON DELETE CASCADE,
|
|
873
|
+
tool TEXT NOT NULL,
|
|
874
|
+
input_tokens INTEGER,
|
|
875
|
+
output_tokens INTEGER,
|
|
876
|
+
cost_micros INTEGER NOT NULL,
|
|
877
|
+
currency TEXT NOT NULL DEFAULT 'USD',
|
|
878
|
+
metadata ${json},
|
|
879
|
+
delegation_chain_id TEXT,
|
|
880
|
+
recorded_at ${ts} NOT NULL
|
|
881
|
+
)`,
|
|
882
|
+
`CREATE INDEX ${ifne} kavach_cost_events_agent_recorded
|
|
883
|
+
ON kavach_cost_events (agent_id, recorded_at DESC)`,
|
|
884
|
+
`CREATE INDEX ${ifne} kavach_cost_events_chain_id
|
|
885
|
+
ON kavach_cost_events (delegation_chain_id)`,
|
|
886
|
+
// ------------------------------------------------------------------
|
|
887
|
+
// kavach_ephemeral_sessions (short-lived agent credentials)
|
|
888
|
+
// ------------------------------------------------------------------
|
|
889
|
+
`CREATE TABLE ${ifne} kavach_ephemeral_sessions (
|
|
890
|
+
id TEXT NOT NULL PRIMARY KEY,
|
|
891
|
+
agent_id TEXT NOT NULL REFERENCES kavach_agents(id) ON DELETE CASCADE,
|
|
892
|
+
owner_id TEXT NOT NULL REFERENCES kavach_users(id),
|
|
893
|
+
token_hash TEXT NOT NULL UNIQUE,
|
|
894
|
+
expires_at ${ts} NOT NULL,
|
|
895
|
+
max_actions INTEGER,
|
|
896
|
+
actions_used INTEGER NOT NULL DEFAULT 0,
|
|
897
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
898
|
+
audit_group_id TEXT NOT NULL,
|
|
899
|
+
created_at ${ts} NOT NULL,
|
|
900
|
+
updated_at ${ts} NOT NULL
|
|
901
|
+
)`,
|
|
902
|
+
`CREATE INDEX ${ifne} kavach_ephemeral_sessions_owner_status
|
|
903
|
+
ON kavach_ephemeral_sessions (owner_id, status)`,
|
|
904
|
+
`CREATE INDEX ${ifne} kavach_ephemeral_sessions_expires_at
|
|
905
|
+
ON kavach_ephemeral_sessions (expires_at)`,
|
|
860
906
|
// ------------------------------------------------------------------
|
|
861
907
|
// kavach_jwt_refresh_tokens (JWT session plugin — general purpose)
|
|
862
908
|
// ------------------------------------------------------------------
|
|
@@ -869,7 +915,84 @@ function buildStatements(provider) {
|
|
|
869
915
|
created_at ${ts} NOT NULL
|
|
870
916
|
)`,
|
|
871
917
|
`CREATE INDEX ${ifne} kavach_jwt_refresh_tokens_user_id
|
|
872
|
-
ON kavach_jwt_refresh_tokens (user_id)
|
|
918
|
+
ON kavach_jwt_refresh_tokens (user_id)`,
|
|
919
|
+
// ------------------------------------------------------------------
|
|
920
|
+
// kavach_stream_events (persisted SSE events for replay)
|
|
921
|
+
// ------------------------------------------------------------------
|
|
922
|
+
`CREATE TABLE ${ifne} kavach_stream_events (
|
|
923
|
+
id TEXT NOT NULL PRIMARY KEY,
|
|
924
|
+
type TEXT NOT NULL,
|
|
925
|
+
timestamp ${ts} NOT NULL,
|
|
926
|
+
data ${json} NOT NULL,
|
|
927
|
+
agent_id TEXT,
|
|
928
|
+
user_id TEXT
|
|
929
|
+
)`,
|
|
930
|
+
`CREATE INDEX ${ifne} kavach_stream_events_timestamp
|
|
931
|
+
ON kavach_stream_events (timestamp DESC)`,
|
|
932
|
+
`CREATE INDEX ${ifne} kavach_stream_events_type_timestamp
|
|
933
|
+
ON kavach_stream_events (type, timestamp DESC)`,
|
|
934
|
+
// ------------------------------------------------------------------
|
|
935
|
+
// kavach_rebac_resources (ReBAC resource hierarchy)
|
|
936
|
+
// ------------------------------------------------------------------
|
|
937
|
+
`CREATE TABLE ${ifne} kavach_rebac_resources (
|
|
938
|
+
id TEXT NOT NULL PRIMARY KEY,
|
|
939
|
+
type TEXT NOT NULL,
|
|
940
|
+
parent_id TEXT,
|
|
941
|
+
parent_type TEXT,
|
|
942
|
+
created_at ${ts} NOT NULL
|
|
943
|
+
)`,
|
|
944
|
+
`CREATE INDEX ${ifne} kavach_rebac_resources_parent
|
|
945
|
+
ON kavach_rebac_resources (parent_id, parent_type)`,
|
|
946
|
+
// ------------------------------------------------------------------
|
|
947
|
+
// kavach_rebac_relationships (Zanzibar-style subject-relation-object tuples)
|
|
948
|
+
// ------------------------------------------------------------------
|
|
949
|
+
`CREATE TABLE ${ifne} kavach_rebac_relationships (
|
|
950
|
+
id TEXT NOT NULL PRIMARY KEY,
|
|
951
|
+
subject_type TEXT NOT NULL,
|
|
952
|
+
subject_id TEXT NOT NULL,
|
|
953
|
+
relation TEXT NOT NULL,
|
|
954
|
+
object_type TEXT NOT NULL,
|
|
955
|
+
object_id TEXT NOT NULL,
|
|
956
|
+
created_at ${ts} NOT NULL
|
|
957
|
+
)`,
|
|
958
|
+
`CREATE INDEX ${ifne} kavach_rebac_relationships_subject
|
|
959
|
+
ON kavach_rebac_relationships (subject_type, subject_id)`,
|
|
960
|
+
`CREATE INDEX ${ifne} kavach_rebac_relationships_object
|
|
961
|
+
ON kavach_rebac_relationships (object_type, object_id)`,
|
|
962
|
+
`CREATE UNIQUE INDEX ${ifne} kavach_rebac_relationships_tuple
|
|
963
|
+
ON kavach_rebac_relationships (subject_type, subject_id, relation, object_type, object_id)`,
|
|
964
|
+
// ------------------------------------------------------------------
|
|
965
|
+
// kavach_federation_instances (trusted remote KavachOS instances)
|
|
966
|
+
// ------------------------------------------------------------------
|
|
967
|
+
`CREATE TABLE ${ifne} kavach_federation_instances (
|
|
968
|
+
id TEXT NOT NULL PRIMARY KEY,
|
|
969
|
+
instance_id TEXT NOT NULL UNIQUE,
|
|
970
|
+
instance_url TEXT NOT NULL,
|
|
971
|
+
public_key_jwk TEXT,
|
|
972
|
+
trust_level TEXT NOT NULL DEFAULT 'verify-only',
|
|
973
|
+
discovered_at ${tsNull},
|
|
974
|
+
created_at ${ts} NOT NULL,
|
|
975
|
+
updated_at ${ts} NOT NULL
|
|
976
|
+
)`,
|
|
977
|
+
// ------------------------------------------------------------------
|
|
978
|
+
// kavach_federation_tokens (issued/received federation tokens)
|
|
979
|
+
// ------------------------------------------------------------------
|
|
980
|
+
`CREATE TABLE ${ifne} kavach_federation_tokens (
|
|
981
|
+
id TEXT NOT NULL PRIMARY KEY,
|
|
982
|
+
token_jti TEXT NOT NULL UNIQUE,
|
|
983
|
+
agent_id TEXT NOT NULL,
|
|
984
|
+
source_instance_id TEXT NOT NULL,
|
|
985
|
+
target_instance_id TEXT,
|
|
986
|
+
direction TEXT NOT NULL,
|
|
987
|
+
permissions ${json} NOT NULL,
|
|
988
|
+
trust_score INTEGER,
|
|
989
|
+
expires_at ${ts} NOT NULL,
|
|
990
|
+
created_at ${ts} NOT NULL
|
|
991
|
+
)`,
|
|
992
|
+
`CREATE INDEX ${ifne} kavach_federation_tokens_agent
|
|
993
|
+
ON kavach_federation_tokens (agent_id)`,
|
|
994
|
+
`CREATE INDEX ${ifne} kavach_federation_tokens_source
|
|
995
|
+
ON kavach_federation_tokens (source_instance_id)`
|
|
873
996
|
// ------------------------------------------------------------------
|
|
874
997
|
// kavach_users ban columns (ALTER TABLE IF NOT EXISTS — safe no-ops)
|
|
875
998
|
// These are appended as separate ALTER statements for existing DBs.
|
|
@@ -960,7 +1083,7 @@ function createDelegationModule(config) {
|
|
|
960
1083
|
`Delegation depth ${currentDepth} exceeds maximum allowed depth of ${maxDepth}. This prevents infinite delegation chains.`
|
|
961
1084
|
);
|
|
962
1085
|
}
|
|
963
|
-
const id =
|
|
1086
|
+
const id = generateId();
|
|
964
1087
|
const now = /* @__PURE__ */ new Date();
|
|
965
1088
|
await db.insert(delegationChains).values({
|
|
966
1089
|
id,
|
|
@@ -2107,7 +2230,7 @@ function isExceeded(limits, usage) {
|
|
|
2107
2230
|
}
|
|
2108
2231
|
function createPolicyModule(db) {
|
|
2109
2232
|
async function create(input) {
|
|
2110
|
-
const id = `pol_${
|
|
2233
|
+
const id = `pol_${generateId().replace(/-/g, "")}`;
|
|
2111
2234
|
const now = /* @__PURE__ */ new Date();
|
|
2112
2235
|
const usage = emptyUsage();
|
|
2113
2236
|
await db.insert(budgetPolicies).values({
|
|
@@ -2262,6 +2385,334 @@ function createPolicyModule(db) {
|
|
|
2262
2385
|
}
|
|
2263
2386
|
return { create, get, list, update, remove, checkBudget, recordUsage, resetDaily, resetMonthly };
|
|
2264
2387
|
}
|
|
2388
|
+
|
|
2389
|
+
// src/redirect/chain.ts
|
|
2390
|
+
var DEFAULT_COOKIE_NAME = "kavach_redirect";
|
|
2391
|
+
var DEFAULT_MAX_AGE = 600;
|
|
2392
|
+
var DEFAULT_PATH = "/";
|
|
2393
|
+
var DEFAULT_MAX_DEPTH = 10;
|
|
2394
|
+
var DEFAULT_EXCLUDE_PATHS = [
|
|
2395
|
+
"/sign-in",
|
|
2396
|
+
"/sign-up",
|
|
2397
|
+
"/forgot-password",
|
|
2398
|
+
"/reset-password",
|
|
2399
|
+
"/verify-email",
|
|
2400
|
+
"/api/"
|
|
2401
|
+
];
|
|
2402
|
+
var encoder = new TextEncoder();
|
|
2403
|
+
var decoder = new TextDecoder();
|
|
2404
|
+
function encodeState(state) {
|
|
2405
|
+
const json = JSON.stringify(state);
|
|
2406
|
+
const bytes = encoder.encode(json);
|
|
2407
|
+
let binary = "";
|
|
2408
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
2409
|
+
binary += String.fromCharCode(bytes[i]);
|
|
2410
|
+
}
|
|
2411
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
2412
|
+
}
|
|
2413
|
+
function decodeState(encoded) {
|
|
2414
|
+
try {
|
|
2415
|
+
let base64 = encoded.replace(/-/g, "+").replace(/_/g, "/");
|
|
2416
|
+
while (base64.length % 4 !== 0) {
|
|
2417
|
+
base64 += "=";
|
|
2418
|
+
}
|
|
2419
|
+
const binary = atob(base64);
|
|
2420
|
+
const bytes = new Uint8Array(binary.length);
|
|
2421
|
+
for (let i = 0; i < binary.length; i++) {
|
|
2422
|
+
bytes[i] = binary.charCodeAt(i);
|
|
2423
|
+
}
|
|
2424
|
+
const json = decoder.decode(bytes);
|
|
2425
|
+
const parsed = JSON.parse(json);
|
|
2426
|
+
if (!isValidChainState(parsed)) return null;
|
|
2427
|
+
return parsed;
|
|
2428
|
+
} catch {
|
|
2429
|
+
return null;
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
function isValidChainState(value) {
|
|
2433
|
+
if (typeof value !== "object" || value === null) return false;
|
|
2434
|
+
const obj = value;
|
|
2435
|
+
if (typeof obj.createdAt !== "number") return false;
|
|
2436
|
+
if (!isValidEntry(obj.origin)) return false;
|
|
2437
|
+
if (!Array.isArray(obj.steps)) return false;
|
|
2438
|
+
for (const step of obj.steps) {
|
|
2439
|
+
if (!isValidEntry(step)) return false;
|
|
2440
|
+
}
|
|
2441
|
+
return true;
|
|
2442
|
+
}
|
|
2443
|
+
function isValidEntry(value) {
|
|
2444
|
+
if (typeof value !== "object" || value === null) return false;
|
|
2445
|
+
const obj = value;
|
|
2446
|
+
return typeof obj.id === "string" && typeof obj.path === "string" && typeof obj.query === "object" && obj.query !== null && typeof obj.hash === "string" && typeof obj.createdAt === "number";
|
|
2447
|
+
}
|
|
2448
|
+
function parseCookies(request) {
|
|
2449
|
+
const header = request.headers.get("cookie");
|
|
2450
|
+
if (!header) return {};
|
|
2451
|
+
const cookies = {};
|
|
2452
|
+
for (const pair of header.split(";")) {
|
|
2453
|
+
const eqIdx = pair.indexOf("=");
|
|
2454
|
+
if (eqIdx === -1) continue;
|
|
2455
|
+
const key = pair.slice(0, eqIdx).trim();
|
|
2456
|
+
const val = pair.slice(eqIdx + 1).trim();
|
|
2457
|
+
cookies[key] = val;
|
|
2458
|
+
}
|
|
2459
|
+
return cookies;
|
|
2460
|
+
}
|
|
2461
|
+
function isExcluded(path, excludePaths) {
|
|
2462
|
+
for (const excluded of excludePaths) {
|
|
2463
|
+
if (excluded.endsWith("/")) {
|
|
2464
|
+
if (path.startsWith(excluded) || path === excluded.slice(0, -1)) return true;
|
|
2465
|
+
} else {
|
|
2466
|
+
if (path === excluded) return true;
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2469
|
+
return false;
|
|
2470
|
+
}
|
|
2471
|
+
function createRedirectChain(config) {
|
|
2472
|
+
const cookieName = config?.cookieName ?? DEFAULT_COOKIE_NAME;
|
|
2473
|
+
const maxAge = config?.maxAge ?? DEFAULT_MAX_AGE;
|
|
2474
|
+
const defaultPath = config?.defaultPath ?? DEFAULT_PATH;
|
|
2475
|
+
const excludePaths = config?.excludePaths ?? DEFAULT_EXCLUDE_PATHS;
|
|
2476
|
+
const preserveQuery = config?.preserveQuery ?? true;
|
|
2477
|
+
const preserveHash = config?.preserveHash ?? true;
|
|
2478
|
+
const maxDepth = config?.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
2479
|
+
const cookieOpts = {
|
|
2480
|
+
httpOnly: config?.cookie?.httpOnly ?? true,
|
|
2481
|
+
secure: config?.cookie?.secure ?? true,
|
|
2482
|
+
sameSite: config?.cookie?.sameSite ?? "lax",
|
|
2483
|
+
path: config?.cookie?.path ?? "/",
|
|
2484
|
+
domain: config?.cookie?.domain
|
|
2485
|
+
};
|
|
2486
|
+
let currentState = null;
|
|
2487
|
+
function buildCookieHeader(value, age) {
|
|
2488
|
+
const parts = [`${cookieName}=${value}`, `Path=${cookieOpts.path}`, `Max-Age=${age}`];
|
|
2489
|
+
if (cookieOpts.httpOnly) parts.push("HttpOnly");
|
|
2490
|
+
if (cookieOpts.secure) parts.push("Secure");
|
|
2491
|
+
parts.push(
|
|
2492
|
+
`SameSite=${cookieOpts.sameSite.charAt(0).toUpperCase()}${cookieOpts.sameSite.slice(1)}`
|
|
2493
|
+
);
|
|
2494
|
+
if (cookieOpts.domain) parts.push(`Domain=${cookieOpts.domain}`);
|
|
2495
|
+
return parts.join("; ");
|
|
2496
|
+
}
|
|
2497
|
+
function buildClearCookie() {
|
|
2498
|
+
return buildCookieHeader("", 0);
|
|
2499
|
+
}
|
|
2500
|
+
function serializeAndSetCookie(state) {
|
|
2501
|
+
currentState = state;
|
|
2502
|
+
const encoded = encodeState(state);
|
|
2503
|
+
return buildCookieHeader(encoded, maxAge);
|
|
2504
|
+
}
|
|
2505
|
+
function parseFromRequest(request) {
|
|
2506
|
+
const cookies = parseCookies(request);
|
|
2507
|
+
const raw = cookies[cookieName];
|
|
2508
|
+
if (!raw) return null;
|
|
2509
|
+
const state = decodeState(raw);
|
|
2510
|
+
if (!state) return null;
|
|
2511
|
+
const elapsed = Date.now() - state.createdAt;
|
|
2512
|
+
if (elapsed > maxAge * 1e3) return null;
|
|
2513
|
+
currentState = state;
|
|
2514
|
+
return state;
|
|
2515
|
+
}
|
|
2516
|
+
function createEntryFromUrl(url, label) {
|
|
2517
|
+
let parsed;
|
|
2518
|
+
if (typeof url === "string") {
|
|
2519
|
+
if (url.startsWith("/")) {
|
|
2520
|
+
parsed = new URL(url, "http://localhost");
|
|
2521
|
+
} else {
|
|
2522
|
+
parsed = new URL(url);
|
|
2523
|
+
}
|
|
2524
|
+
} else {
|
|
2525
|
+
parsed = new URL(url.url);
|
|
2526
|
+
}
|
|
2527
|
+
const query = {};
|
|
2528
|
+
if (preserveQuery) {
|
|
2529
|
+
parsed.searchParams.forEach((value, key) => {
|
|
2530
|
+
query[key] = value;
|
|
2531
|
+
});
|
|
2532
|
+
}
|
|
2533
|
+
return {
|
|
2534
|
+
id: generateId(),
|
|
2535
|
+
path: parsed.pathname,
|
|
2536
|
+
query,
|
|
2537
|
+
hash: preserveHash ? parsed.hash.replace(/^#/, "") : "",
|
|
2538
|
+
createdAt: Date.now(),
|
|
2539
|
+
label
|
|
2540
|
+
};
|
|
2541
|
+
}
|
|
2542
|
+
function buildUrlFromEntry(entry) {
|
|
2543
|
+
let url = entry.path;
|
|
2544
|
+
const params = Object.entries(entry.query);
|
|
2545
|
+
if (params.length > 0) {
|
|
2546
|
+
const searchParams = new URLSearchParams();
|
|
2547
|
+
for (const [key, value] of params) {
|
|
2548
|
+
searchParams.set(key, value);
|
|
2549
|
+
}
|
|
2550
|
+
url += `?${searchParams.toString()}`;
|
|
2551
|
+
}
|
|
2552
|
+
if (entry.hash) {
|
|
2553
|
+
url += `#${entry.hash}`;
|
|
2554
|
+
}
|
|
2555
|
+
return url;
|
|
2556
|
+
}
|
|
2557
|
+
const manager = {
|
|
2558
|
+
capture(request) {
|
|
2559
|
+
const existing = parseFromRequest(request);
|
|
2560
|
+
if (existing) {
|
|
2561
|
+
return serializeAndSetCookie(existing);
|
|
2562
|
+
}
|
|
2563
|
+
const entry = createEntryFromUrl(request);
|
|
2564
|
+
if (isExcluded(entry.path, excludePaths)) {
|
|
2565
|
+
entry.path = defaultPath;
|
|
2566
|
+
entry.query = {};
|
|
2567
|
+
entry.hash = "";
|
|
2568
|
+
}
|
|
2569
|
+
const state = {
|
|
2570
|
+
origin: entry,
|
|
2571
|
+
steps: [],
|
|
2572
|
+
createdAt: Date.now()
|
|
2573
|
+
};
|
|
2574
|
+
return serializeAndSetCookie(state);
|
|
2575
|
+
},
|
|
2576
|
+
push(path, options) {
|
|
2577
|
+
if (!currentState) {
|
|
2578
|
+
currentState = {
|
|
2579
|
+
origin: {
|
|
2580
|
+
id: generateId(),
|
|
2581
|
+
path: defaultPath,
|
|
2582
|
+
query: {},
|
|
2583
|
+
hash: "",
|
|
2584
|
+
createdAt: Date.now()
|
|
2585
|
+
},
|
|
2586
|
+
steps: [],
|
|
2587
|
+
createdAt: Date.now()
|
|
2588
|
+
};
|
|
2589
|
+
}
|
|
2590
|
+
if (currentState.steps.length >= maxDepth) {
|
|
2591
|
+
return serializeAndSetCookie(currentState);
|
|
2592
|
+
}
|
|
2593
|
+
const entry = {
|
|
2594
|
+
id: generateId(),
|
|
2595
|
+
path,
|
|
2596
|
+
query: options?.query ?? {},
|
|
2597
|
+
hash: "",
|
|
2598
|
+
createdAt: Date.now(),
|
|
2599
|
+
label: options?.label
|
|
2600
|
+
};
|
|
2601
|
+
currentState.steps.push(entry);
|
|
2602
|
+
return serializeAndSetCookie(currentState);
|
|
2603
|
+
},
|
|
2604
|
+
pop(request) {
|
|
2605
|
+
const state = parseFromRequest(request);
|
|
2606
|
+
if (!state) {
|
|
2607
|
+
return { url: defaultPath, done: true, clearCookie: buildClearCookie() };
|
|
2608
|
+
}
|
|
2609
|
+
if (state.steps.length > 0) {
|
|
2610
|
+
const next = state.steps.shift();
|
|
2611
|
+
const url2 = buildUrlFromEntry(next);
|
|
2612
|
+
if (state.steps.length === 0) {
|
|
2613
|
+
currentState = state;
|
|
2614
|
+
return {
|
|
2615
|
+
url: url2,
|
|
2616
|
+
done: false,
|
|
2617
|
+
clearCookie: null
|
|
2618
|
+
};
|
|
2619
|
+
}
|
|
2620
|
+
return {
|
|
2621
|
+
url: url2,
|
|
2622
|
+
done: false,
|
|
2623
|
+
clearCookie: null
|
|
2624
|
+
};
|
|
2625
|
+
}
|
|
2626
|
+
const url = buildUrlFromEntry(state.origin);
|
|
2627
|
+
currentState = null;
|
|
2628
|
+
return {
|
|
2629
|
+
url,
|
|
2630
|
+
done: true,
|
|
2631
|
+
clearCookie: buildClearCookie()
|
|
2632
|
+
};
|
|
2633
|
+
},
|
|
2634
|
+
peek(request) {
|
|
2635
|
+
const state = parseFromRequest(request);
|
|
2636
|
+
if (!state) return null;
|
|
2637
|
+
if (state.steps.length > 0) {
|
|
2638
|
+
const next = state.steps[0];
|
|
2639
|
+
return {
|
|
2640
|
+
url: buildUrlFromEntry(next),
|
|
2641
|
+
remaining: state.steps.length
|
|
2642
|
+
// +origin is implicit
|
|
2643
|
+
};
|
|
2644
|
+
}
|
|
2645
|
+
return {
|
|
2646
|
+
url: buildUrlFromEntry(state.origin),
|
|
2647
|
+
remaining: 0
|
|
2648
|
+
};
|
|
2649
|
+
},
|
|
2650
|
+
getOrigin(request) {
|
|
2651
|
+
const state = parseFromRequest(request);
|
|
2652
|
+
if (!state) return null;
|
|
2653
|
+
return state.origin;
|
|
2654
|
+
},
|
|
2655
|
+
clear() {
|
|
2656
|
+
currentState = null;
|
|
2657
|
+
return buildClearCookie();
|
|
2658
|
+
},
|
|
2659
|
+
parse(request) {
|
|
2660
|
+
return parseFromRequest(request);
|
|
2661
|
+
},
|
|
2662
|
+
buildUrl(entry) {
|
|
2663
|
+
return buildUrlFromEntry(entry);
|
|
2664
|
+
},
|
|
2665
|
+
createEntry(url, label) {
|
|
2666
|
+
return createEntryFromUrl(url, label);
|
|
2667
|
+
}
|
|
2668
|
+
};
|
|
2669
|
+
return manager;
|
|
2670
|
+
}
|
|
2671
|
+
|
|
2672
|
+
// src/session/freshness.ts
|
|
2673
|
+
var DEFAULT_FRESH_AGE_SECONDS = 300;
|
|
2674
|
+
function createSessionFreshnessModule(config = {}) {
|
|
2675
|
+
const freshAge = config.freshAge ?? DEFAULT_FRESH_AGE_SECONDS;
|
|
2676
|
+
function isFresh(session) {
|
|
2677
|
+
const now = Date.now();
|
|
2678
|
+
const createdAt = session.createdAt.getTime();
|
|
2679
|
+
return now - createdAt < freshAge * 1e3;
|
|
2680
|
+
}
|
|
2681
|
+
function requireFresh(session) {
|
|
2682
|
+
if (isFresh(session)) {
|
|
2683
|
+
const freshUntil = new Date(session.createdAt.getTime() + freshAge * 1e3);
|
|
2684
|
+
return { success: true, data: { freshUntil } };
|
|
2685
|
+
}
|
|
2686
|
+
return {
|
|
2687
|
+
success: false,
|
|
2688
|
+
error: {
|
|
2689
|
+
code: "SESSION_NOT_FRESH",
|
|
2690
|
+
message: "Session is not fresh. Please re-authenticate to perform this action.",
|
|
2691
|
+
details: {
|
|
2692
|
+
createdAt: session.createdAt.toISOString(),
|
|
2693
|
+
freshAge,
|
|
2694
|
+
requiredAfter: new Date(session.createdAt.getTime() + freshAge * 1e3).toISOString()
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
};
|
|
2698
|
+
}
|
|
2699
|
+
function guard(session) {
|
|
2700
|
+
if (isFresh(session)) return null;
|
|
2701
|
+
return new Response(
|
|
2702
|
+
JSON.stringify({
|
|
2703
|
+
error: {
|
|
2704
|
+
code: "SESSION_NOT_FRESH",
|
|
2705
|
+
message: "Session is not fresh. Please re-authenticate to perform this action."
|
|
2706
|
+
}
|
|
2707
|
+
}),
|
|
2708
|
+
{
|
|
2709
|
+
status: 403,
|
|
2710
|
+
headers: { "Content-Type": "application/json" }
|
|
2711
|
+
}
|
|
2712
|
+
);
|
|
2713
|
+
}
|
|
2714
|
+
return { isFresh, requireFresh, guard };
|
|
2715
|
+
}
|
|
2265
2716
|
function slugRegex() {
|
|
2266
2717
|
return /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
2267
2718
|
}
|
|
@@ -2287,7 +2738,7 @@ function createTenantModule(db) {
|
|
|
2287
2738
|
if (existing.length > 0) {
|
|
2288
2739
|
throw new Error(`Tenant with slug "${input.slug}" already exists.`);
|
|
2289
2740
|
}
|
|
2290
|
-
const id = `tnt_${
|
|
2741
|
+
const id = `tnt_${generateId().replace(/-/g, "")}`;
|
|
2291
2742
|
const now = /* @__PURE__ */ new Date();
|
|
2292
2743
|
const settings = input.settings ?? {};
|
|
2293
2744
|
await db.insert(tenants).values({
|
|
@@ -2529,8 +2980,12 @@ async function createKavach(config) {
|
|
|
2529
2980
|
const adminModule = config.admin ? createAdminModule(config.admin, db, sessionManager) : null;
|
|
2530
2981
|
const apiKeyManagerModule = config.apiKeys ? createApiKeyManagerModule(config.apiKeys, db) : null;
|
|
2531
2982
|
const usernameModule = config.username && sessionManager ? createUsernameAuthModule(config.username, db, sessionManager) : null;
|
|
2983
|
+
const oneTimeTokenModule = createOneTimeTokenModule({}, db);
|
|
2984
|
+
const passwordResetModule = config.passwordReset && sessionManager ? createPasswordResetModule(config.passwordReset, db, sessionManager, oneTimeTokenModule) : null;
|
|
2985
|
+
const emailVerificationModule = config.emailVerification ? createEmailVerificationModule(config.emailVerification, db, oneTimeTokenModule) : null;
|
|
2532
2986
|
const phoneModule = config.phone && sessionManager ? createPhoneAuthModule(config.phone, db, sessionManager) : null;
|
|
2533
2987
|
const captchaModule = config.captcha ? createCaptchaModule(config.captcha) : null;
|
|
2988
|
+
const redirectChain = createRedirectChain(config.redirects);
|
|
2534
2989
|
const webhookModule = config.webhooks && config.webhooks.length > 0 ? createWebhookModule(config.webhooks) : null;
|
|
2535
2990
|
const pluginRegistry = await initializePlugins(config.plugins ?? [], db, config);
|
|
2536
2991
|
const endpointCtx = {
|
|
@@ -2673,7 +3128,7 @@ async function createKavach(config) {
|
|
|
2673
3128
|
*/
|
|
2674
3129
|
async register(input) {
|
|
2675
3130
|
const now = /* @__PURE__ */ new Date();
|
|
2676
|
-
const id =
|
|
3131
|
+
const id = generateId();
|
|
2677
3132
|
await db.insert(mcpServers).values({
|
|
2678
3133
|
id,
|
|
2679
3134
|
name: input.name,
|
|
@@ -2967,6 +3422,65 @@ async function createKavach(config) {
|
|
|
2967
3422
|
* ```
|
|
2968
3423
|
*/
|
|
2969
3424
|
username: usernameModule,
|
|
3425
|
+
/**
|
|
3426
|
+
* Password reset (forgot password + reset password).
|
|
3427
|
+
*
|
|
3428
|
+
* Null when `passwordReset` config was not provided or `auth.session`
|
|
3429
|
+
* is not configured.
|
|
3430
|
+
*
|
|
3431
|
+
* @example
|
|
3432
|
+
* ```typescript
|
|
3433
|
+
* // In your route handler
|
|
3434
|
+
* const response = await kavach.passwordReset?.handleRequest(request);
|
|
3435
|
+
* if (response) return response;
|
|
3436
|
+
*
|
|
3437
|
+
* // Or programmatically
|
|
3438
|
+
* await kavach.passwordReset?.requestReset('alice@example.com');
|
|
3439
|
+
* await kavach.passwordReset?.resetPassword(token, 'new-password');
|
|
3440
|
+
* ```
|
|
3441
|
+
*/
|
|
3442
|
+
passwordReset: passwordResetModule,
|
|
3443
|
+
/**
|
|
3444
|
+
* Email address verification.
|
|
3445
|
+
*
|
|
3446
|
+
* Null when `emailVerification` config was not provided.
|
|
3447
|
+
*
|
|
3448
|
+
* @example
|
|
3449
|
+
* ```typescript
|
|
3450
|
+
* // Send a verification email after sign-up
|
|
3451
|
+
* await kavach.emailVerification?.sendVerification(userId, email);
|
|
3452
|
+
*
|
|
3453
|
+
* // Confirm from the link in the email
|
|
3454
|
+
* const result = await kavach.emailVerification?.verify(token);
|
|
3455
|
+
*
|
|
3456
|
+
* // Check status
|
|
3457
|
+
* const verified = await kavach.emailVerification?.isVerified(userId);
|
|
3458
|
+
* ```
|
|
3459
|
+
*/
|
|
3460
|
+
emailVerification: emailVerificationModule,
|
|
3461
|
+
/**
|
|
3462
|
+
* One-time tokens (email verify, password reset, invitations, custom).
|
|
3463
|
+
*
|
|
3464
|
+
* Always available. Used internally by password reset but exposed for
|
|
3465
|
+
* custom flows (email verification, invitation links, etc.).
|
|
3466
|
+
*/
|
|
3467
|
+
oneTimeTokens: oneTimeTokenModule,
|
|
3468
|
+
/**
|
|
3469
|
+
* Session freshness enforcement for sensitive operations.
|
|
3470
|
+
*
|
|
3471
|
+
* Use as middleware before password changes, passkey registration,
|
|
3472
|
+
* billing updates, or any action that requires a recently-authenticated
|
|
3473
|
+
* session rather than an auto-refreshed one.
|
|
3474
|
+
*
|
|
3475
|
+
* @example
|
|
3476
|
+
* ```typescript
|
|
3477
|
+
* const stale = kavach.sessionFreshness.guard(session);
|
|
3478
|
+
* if (stale) return stale; // 403 SESSION_NOT_FRESH
|
|
3479
|
+
* ```
|
|
3480
|
+
*/
|
|
3481
|
+
sessionFreshness: createSessionFreshnessModule(
|
|
3482
|
+
config.sessionFreshness
|
|
3483
|
+
),
|
|
2970
3484
|
/**
|
|
2971
3485
|
* Phone number (SMS OTP) authentication.
|
|
2972
3486
|
*
|
|
@@ -3003,6 +3517,27 @@ async function createKavach(config) {
|
|
|
3003
3517
|
* ```
|
|
3004
3518
|
*/
|
|
3005
3519
|
webhooks: webhookModule,
|
|
3520
|
+
/**
|
|
3521
|
+
* Redirect chain manager.
|
|
3522
|
+
*
|
|
3523
|
+
* Capture the user's original destination before auth redirects, push
|
|
3524
|
+
* intermediate steps (onboarding, email verification), and pop them
|
|
3525
|
+
* back in order. Cookie-based, works across page transitions and tabs.
|
|
3526
|
+
*
|
|
3527
|
+
* @example
|
|
3528
|
+
* ```typescript
|
|
3529
|
+
* // In auth middleware — save where the user was going
|
|
3530
|
+
* const setCookie = kavach.redirects.capture(request);
|
|
3531
|
+
* return new Response(null, { status: 302, headers: { Location: '/sign-in', 'Set-Cookie': setCookie } });
|
|
3532
|
+
*
|
|
3533
|
+
* // After sign-in — send user to their original destination
|
|
3534
|
+
* const { url, clearCookie } = kavach.redirects.pop(request);
|
|
3535
|
+
* const headers: Record<string, string> = { Location: url };
|
|
3536
|
+
* if (clearCookie) headers['Set-Cookie'] = clearCookie;
|
|
3537
|
+
* return new Response(null, { status: 302, headers });
|
|
3538
|
+
* ```
|
|
3539
|
+
*/
|
|
3540
|
+
redirects: redirectChain,
|
|
3006
3541
|
/**
|
|
3007
3542
|
* Plugin system.
|
|
3008
3543
|
*
|
|
@@ -3479,7 +4014,7 @@ function serializeCookieDeletion(name, options) {
|
|
|
3479
4014
|
expires: /* @__PURE__ */ new Date(0)
|
|
3480
4015
|
});
|
|
3481
4016
|
}
|
|
3482
|
-
function
|
|
4017
|
+
function parseCookies2(header) {
|
|
3483
4018
|
const result = {};
|
|
3484
4019
|
if (!header || !header.trim()) return result;
|
|
3485
4020
|
for (const pair of header.split(";")) {
|
|
@@ -3496,10 +4031,10 @@ function parseCookies(header) {
|
|
|
3496
4031
|
return result;
|
|
3497
4032
|
}
|
|
3498
4033
|
function getCookie(header, name) {
|
|
3499
|
-
return
|
|
4034
|
+
return parseCookies2(header)[name];
|
|
3500
4035
|
}
|
|
3501
4036
|
function parseCookiesFromRequest(request) {
|
|
3502
|
-
return
|
|
4037
|
+
return parseCookies2(request.headers.get("cookie") ?? "");
|
|
3503
4038
|
}
|
|
3504
4039
|
function capitalize(s) {
|
|
3505
4040
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
@@ -3793,15 +4328,15 @@ function buildSessionMetadata(request, extra) {
|
|
|
3793
4328
|
}
|
|
3794
4329
|
|
|
3795
4330
|
// src/webhooks/webhook.ts
|
|
3796
|
-
function
|
|
4331
|
+
function generateId2() {
|
|
3797
4332
|
const bytes = new Uint8Array(16);
|
|
3798
4333
|
crypto.getRandomValues(bytes);
|
|
3799
4334
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
3800
4335
|
}
|
|
3801
4336
|
async function signPayload2(secret, body) {
|
|
3802
|
-
const
|
|
3803
|
-
const keyData =
|
|
3804
|
-
const messageData =
|
|
4337
|
+
const encoder2 = new TextEncoder();
|
|
4338
|
+
const keyData = encoder2.encode(secret);
|
|
4339
|
+
const messageData = encoder2.encode(body);
|
|
3805
4340
|
const key = await crypto.subtle.importKey(
|
|
3806
4341
|
"raw",
|
|
3807
4342
|
keyData,
|
|
@@ -3838,7 +4373,7 @@ async function deliverWebhook(url, event, payload, deliveryId, timestamp, signat
|
|
|
3838
4373
|
}
|
|
3839
4374
|
}
|
|
3840
4375
|
async function dispatchWithRetry(url, event, payload, config) {
|
|
3841
|
-
const deliveryId =
|
|
4376
|
+
const deliveryId = generateId2();
|
|
3842
4377
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3843
4378
|
const body = JSON.stringify(payload);
|
|
3844
4379
|
const signature = await signPayload2(config.secret, body);
|
|
@@ -3870,7 +4405,7 @@ function createWebhookModule2(config) {
|
|
|
3870
4405
|
const subscriptions = /* @__PURE__ */ new Map();
|
|
3871
4406
|
async function subscribe(url, events) {
|
|
3872
4407
|
const sub = {
|
|
3873
|
-
id:
|
|
4408
|
+
id: generateId2(),
|
|
3874
4409
|
url,
|
|
3875
4410
|
events,
|
|
3876
4411
|
active: true,
|
|
@@ -3898,7 +4433,7 @@ function createWebhookModule2(config) {
|
|
|
3898
4433
|
if (!sub) {
|
|
3899
4434
|
return { success: false, error: "Subscription not found" };
|
|
3900
4435
|
}
|
|
3901
|
-
const deliveryId =
|
|
4436
|
+
const deliveryId = generateId2();
|
|
3902
4437
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3903
4438
|
const pingPayload = { event: "ping", subscriptionId, timestamp };
|
|
3904
4439
|
const body = JSON.stringify(pingPayload);
|
|
@@ -3928,6 +4463,6 @@ async function verifyWebhookSignature(secret, rawBody, signature) {
|
|
|
3928
4463
|
return diff === 0;
|
|
3929
4464
|
}
|
|
3930
4465
|
|
|
3931
|
-
export { MultiSessionLimitError, buildDidDocument, buildSessionMetadata, classifyViolation, createApprovalModule, createCookieSessionManager, createDatabase, createDatabaseSync, createDelegationModule, createDidModule, createEmailTemplates, createI18n, createKavach, createMultiSessionModule, createPluginRouter, createPolicyModule, createPresentation, createPrivilegeAnalyzer, createTables, createTenantModule, createTrustModule, createWebhookModule2 as createWebhookModule, de, en, es, fr, generateCsrfToken, generateDidKey, generateDidWeb, generateOpenAPISpec, getCookie, getDidWebUrl, initializePlugins, ja, parseCookies, parseCookiesFromRequest, resolveDidKey, resolveDidWeb, serializeCookie, serializeCookieDeletion, signPayload, validateCsrfToken, validateOrigin, verifyPayload, verifyPresentation, verifyWebhookSignature, zh };
|
|
4466
|
+
export { MultiSessionLimitError, buildDidDocument, buildSessionMetadata, classifyViolation, createApprovalModule, createCookieSessionManager, createDatabase, createDatabaseSync, createDelegationModule, createDidModule, createEmailTemplates, createI18n, createKavach, createMultiSessionModule, createPluginRouter, createPolicyModule, createPresentation, createPrivilegeAnalyzer, createRedirectChain, createSessionFreshnessModule, createTables, createTenantModule, createTrustModule, createWebhookModule2 as createWebhookModule, de, en, es, fr, generateCsrfToken, generateDidKey, generateDidWeb, generateOpenAPISpec, getCookie, getDidWebUrl, initializePlugins, ja, parseCookies2 as parseCookies, parseCookiesFromRequest, resolveDidKey, resolveDidWeb, serializeCookie, serializeCookieDeletion, signPayload, validateCsrfToken, validateOrigin, verifyPayload, verifyPresentation, verifyWebhookSignature, zh };
|
|
3932
4467
|
//# sourceMappingURL=index.js.map
|
|
3933
4468
|
//# sourceMappingURL=index.js.map
|