@spfn/auth 0.1.0-alpha.0 → 0.1.0-alpha.86
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/LICENSE +21 -0
- package/README.md +320 -12
- package/dist/adapters/nextjs/api.d.ts +446 -0
- package/dist/adapters/nextjs/api.js +3279 -0
- package/dist/adapters/nextjs/api.js.map +1 -0
- package/dist/adapters/nextjs/server.d.ts +246 -0
- package/dist/adapters/nextjs/server.js +3645 -0
- package/dist/adapters/nextjs/server.js.map +1 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.js +1 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +9098 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api/auth-codes-verify.d.ts +37 -0
- package/dist/lib/api/auth-codes-verify.js +2949 -0
- package/dist/lib/api/auth-codes-verify.js.map +1 -0
- package/dist/lib/api/auth-codes.d.ts +37 -0
- package/dist/lib/api/auth-codes.js +2949 -0
- package/dist/lib/api/auth-codes.js.map +1 -0
- package/dist/lib/api/auth-exists.d.ts +38 -0
- package/dist/lib/api/auth-exists.js +2949 -0
- package/dist/lib/api/auth-exists.js.map +1 -0
- package/dist/lib/api/auth-invitations-accept.d.ts +38 -0
- package/dist/lib/api/auth-invitations-accept.js +2883 -0
- package/dist/lib/api/auth-invitations-accept.js.map +1 -0
- package/dist/lib/api/auth-invitations-cancel.d.ts +37 -0
- package/dist/lib/api/auth-invitations-cancel.js +2883 -0
- package/dist/lib/api/auth-invitations-cancel.js.map +1 -0
- package/dist/lib/api/auth-invitations-delete.d.ts +36 -0
- package/dist/lib/api/auth-invitations-delete.js +2883 -0
- package/dist/lib/api/auth-invitations-delete.js.map +1 -0
- package/dist/lib/api/auth-invitations-resend.d.ts +37 -0
- package/dist/lib/api/auth-invitations-resend.js +2883 -0
- package/dist/lib/api/auth-invitations-resend.js.map +1 -0
- package/dist/lib/api/auth-invitations.d.ts +109 -0
- package/dist/lib/api/auth-invitations.js +2887 -0
- package/dist/lib/api/auth-invitations.js.map +1 -0
- package/dist/lib/api/auth-keys-rotate.d.ts +37 -0
- package/dist/lib/api/auth-keys-rotate.js +2949 -0
- package/dist/lib/api/auth-keys-rotate.js.map +1 -0
- package/dist/lib/api/auth-login.d.ts +39 -0
- package/dist/lib/api/auth-login.js +2949 -0
- package/dist/lib/api/auth-login.js.map +1 -0
- package/dist/lib/api/auth-logout.d.ts +36 -0
- package/dist/lib/api/auth-logout.js +2949 -0
- package/dist/lib/api/auth-logout.js.map +1 -0
- package/dist/lib/api/auth-me.d.ts +50 -0
- package/dist/lib/api/auth-me.js +2949 -0
- package/dist/lib/api/auth-me.js.map +1 -0
- package/dist/lib/api/auth-password.d.ts +36 -0
- package/dist/lib/api/auth-password.js +2949 -0
- package/dist/lib/api/auth-password.js.map +1 -0
- package/dist/lib/api/auth-register.d.ts +38 -0
- package/dist/lib/api/auth-register.js +2949 -0
- package/dist/lib/api/auth-register.js.map +1 -0
- package/dist/lib/api/index.d.ts +356 -0
- package/dist/lib/api/index.js +3261 -0
- package/dist/lib/api/index.js.map +1 -0
- package/dist/lib/config.d.ts +70 -0
- package/dist/lib/config.js +64 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/contracts/auth.d.ts +302 -0
- package/dist/lib/contracts/auth.js +2951 -0
- package/dist/lib/contracts/auth.js.map +1 -0
- package/dist/lib/contracts/index.d.ts +3 -0
- package/dist/lib/contracts/index.js +3190 -0
- package/dist/lib/contracts/index.js.map +1 -0
- package/dist/lib/contracts/invitation.d.ts +243 -0
- package/dist/lib/contracts/invitation.js +2883 -0
- package/dist/lib/contracts/invitation.js.map +1 -0
- package/dist/lib/crypto.d.ts +76 -0
- package/dist/lib/crypto.js +127 -0
- package/dist/lib/crypto.js.map +1 -0
- package/dist/lib/index.d.ts +4 -0
- package/dist/lib/index.js +313 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/session.d.ts +68 -0
- package/dist/lib/session.js +126 -0
- package/dist/lib/session.js.map +1 -0
- package/dist/lib/types/api.d.ts +45 -0
- package/dist/lib/types/api.js +1 -0
- package/dist/lib/types/api.js.map +1 -0
- package/dist/lib/types/index.d.ts +3 -0
- package/dist/lib/types/index.js +2647 -0
- package/dist/lib/types/index.js.map +1 -0
- package/dist/lib/types/schemas.d.ts +45 -0
- package/dist/lib/types/schemas.js +2647 -0
- package/dist/lib/types/schemas.js.map +1 -0
- package/dist/lib.d.ts +2 -0
- package/dist/lib.js +1 -0
- package/dist/lib.js.map +1 -0
- package/dist/plugin.d.ts +12 -0
- package/dist/plugin.js +9081 -0
- package/dist/plugin.js.map +1 -0
- package/dist/server/entities/index.d.ts +11 -0
- package/dist/server/entities/index.js +395 -0
- package/dist/server/entities/index.js.map +1 -0
- package/dist/server/entities/invitations.d.ts +241 -0
- package/dist/server/entities/invitations.js +184 -0
- package/dist/server/entities/invitations.js.map +1 -0
- package/dist/server/entities/permissions.d.ts +196 -0
- package/dist/server/entities/permissions.js +49 -0
- package/dist/server/entities/permissions.js.map +1 -0
- package/dist/server/entities/role-permissions.d.ts +107 -0
- package/dist/server/entities/role-permissions.js +115 -0
- package/dist/server/entities/role-permissions.js.map +1 -0
- package/dist/server/entities/roles.d.ts +196 -0
- package/dist/server/entities/roles.js +50 -0
- package/dist/server/entities/roles.js.map +1 -0
- package/dist/server/entities/schema.d.ts +14 -0
- package/dist/server/entities/schema.js +7 -0
- package/dist/server/entities/schema.js.map +1 -0
- package/dist/server/entities/user-permissions.d.ts +163 -0
- package/dist/server/entities/user-permissions.js +193 -0
- package/dist/server/entities/user-permissions.js.map +1 -0
- package/dist/server/entities/user-public-keys.d.ts +227 -0
- package/dist/server/entities/user-public-keys.js +156 -0
- package/dist/server/entities/user-public-keys.js.map +1 -0
- package/dist/server/entities/user-social-accounts.d.ts +189 -0
- package/dist/server/entities/user-social-accounts.js +149 -0
- package/dist/server/entities/user-social-accounts.js.map +1 -0
- package/dist/server/entities/users.d.ts +235 -0
- package/dist/server/entities/users.js +117 -0
- package/dist/server/entities/users.js.map +1 -0
- package/dist/server/entities/verification-codes.d.ts +191 -0
- package/dist/server/entities/verification-codes.js +49 -0
- package/dist/server/entities/verification-codes.js.map +1 -0
- package/dist/server/routes/auth/index.d.ts +10 -0
- package/dist/server/routes/auth/index.js +4458 -0
- package/dist/server/routes/auth/index.js.map +1 -0
- package/dist/server/routes/index.d.ts +6 -0
- package/dist/server/routes/index.js +6582 -0
- package/dist/server/routes/index.js.map +1 -0
- package/dist/server/routes/invitations/index.d.ts +10 -0
- package/dist/server/routes/invitations/index.js +4395 -0
- package/dist/server/routes/invitations/index.js.map +1 -0
- package/dist/server.d.ts +1272 -0
- package/dist/server.js +2274 -0
- package/dist/server.js.map +1 -0
- package/migrations/0000_complex_swordsman.sql +167 -0
- package/migrations/meta/0000_snapshot.json +1397 -0
- package/migrations/meta/_journal.json +13 -0
- package/package.json +59 -24
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// src/lib/session.ts
|
|
2
|
+
import * as jose from "jose";
|
|
3
|
+
function calculateEntropy(str) {
|
|
4
|
+
const len = str.length;
|
|
5
|
+
const frequencies = /* @__PURE__ */ new Map();
|
|
6
|
+
for (const char of str) {
|
|
7
|
+
frequencies.set(char, (frequencies.get(char) || 0) + 1);
|
|
8
|
+
}
|
|
9
|
+
let entropy = 0;
|
|
10
|
+
for (const count of frequencies.values()) {
|
|
11
|
+
const probability = count / len;
|
|
12
|
+
entropy -= probability * Math.log2(probability);
|
|
13
|
+
}
|
|
14
|
+
return entropy;
|
|
15
|
+
}
|
|
16
|
+
async function getSessionSecret() {
|
|
17
|
+
const secret = process.env.SPFN_AUTH_SESSION_SECRET || // New prefixed version (recommended)
|
|
18
|
+
process.env.SESSION_SECRET;
|
|
19
|
+
if (!secret) {
|
|
20
|
+
throw new Error("SPFN_AUTH_SESSION_SECRET environment variable is not set");
|
|
21
|
+
}
|
|
22
|
+
if (secret.length < 32) {
|
|
23
|
+
throw new Error("SPFN_AUTH_SESSION_SECRET must be at least 32 characters long");
|
|
24
|
+
}
|
|
25
|
+
const encoder = new TextEncoder();
|
|
26
|
+
const data = encoder.encode(secret);
|
|
27
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
28
|
+
return new Uint8Array(hashBuffer);
|
|
29
|
+
}
|
|
30
|
+
async function sealSession(data, ttl = 60 * 60 * 24 * 7) {
|
|
31
|
+
const secret = await getSessionSecret();
|
|
32
|
+
return await new jose.EncryptJWT({ data }).setProtectedHeader({ alg: "dir", enc: "A256GCM" }).setIssuedAt().setExpirationTime(`${ttl}s`).setIssuer("spfn-auth").setAudience("spfn-client").encrypt(secret);
|
|
33
|
+
}
|
|
34
|
+
async function unsealSession(jwt) {
|
|
35
|
+
const secret = await getSessionSecret();
|
|
36
|
+
try {
|
|
37
|
+
const { payload } = await jose.jwtDecrypt(jwt, secret, {
|
|
38
|
+
issuer: "spfn-auth",
|
|
39
|
+
audience: "spfn-client"
|
|
40
|
+
});
|
|
41
|
+
return payload.data;
|
|
42
|
+
} catch (err) {
|
|
43
|
+
if (err instanceof jose.errors.JWTExpired) {
|
|
44
|
+
throw new Error("Session expired");
|
|
45
|
+
}
|
|
46
|
+
if (err instanceof jose.errors.JWEDecryptionFailed) {
|
|
47
|
+
throw new Error("Invalid session");
|
|
48
|
+
}
|
|
49
|
+
if (err instanceof jose.errors.JWTClaimValidationFailed) {
|
|
50
|
+
throw new Error("Session validation failed");
|
|
51
|
+
}
|
|
52
|
+
throw new Error("Failed to unseal session");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function getSessionInfo(jwt) {
|
|
56
|
+
const secret = await getSessionSecret();
|
|
57
|
+
try {
|
|
58
|
+
const { payload } = await jose.jwtDecrypt(jwt, secret);
|
|
59
|
+
return {
|
|
60
|
+
issuedAt: new Date(payload.iat * 1e3),
|
|
61
|
+
expiresAt: new Date(payload.exp * 1e3),
|
|
62
|
+
issuer: payload.iss || "",
|
|
63
|
+
audience: Array.isArray(payload.aud) ? payload.aud[0] : payload.aud || ""
|
|
64
|
+
};
|
|
65
|
+
} catch (err) {
|
|
66
|
+
if (process.env.NODE_ENV !== "production") {
|
|
67
|
+
console.warn("[Session] Failed to get session info:", err instanceof Error ? err.message : "Unknown error");
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function shouldRefreshSession(jwt, thresholdHours = 24) {
|
|
73
|
+
const info = await getSessionInfo(jwt);
|
|
74
|
+
if (!info) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
const hoursRemaining = (info.expiresAt.getTime() - Date.now()) / (1e3 * 60 * 60);
|
|
78
|
+
return hoursRemaining < thresholdHours;
|
|
79
|
+
}
|
|
80
|
+
function validateSessionSecret() {
|
|
81
|
+
try {
|
|
82
|
+
const secret = process.env.SPFN_AUTH_SESSION_SECRET || // New prefixed version (recommended)
|
|
83
|
+
process.env.SESSION_SECRET;
|
|
84
|
+
if (!secret) {
|
|
85
|
+
return { valid: false, error: "SPFN_AUTH_SESSION_SECRET is not set" };
|
|
86
|
+
}
|
|
87
|
+
const length = secret.length;
|
|
88
|
+
const uniqueChars = new Set(secret).size;
|
|
89
|
+
const entropy = calculateEntropy(secret);
|
|
90
|
+
if (length < 32) {
|
|
91
|
+
return {
|
|
92
|
+
valid: false,
|
|
93
|
+
error: `SPFN_AUTH_SESSION_SECRET too short (${length} chars, minimum 32)`,
|
|
94
|
+
details: { length, uniqueChars, entropy }
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
if (uniqueChars < 16) {
|
|
98
|
+
return {
|
|
99
|
+
valid: false,
|
|
100
|
+
error: `SPFN_AUTH_SESSION_SECRET has low diversity (${uniqueChars} unique chars, minimum 16)`,
|
|
101
|
+
details: { length, uniqueChars, entropy }
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
if (entropy < 3.5) {
|
|
105
|
+
return {
|
|
106
|
+
valid: false,
|
|
107
|
+
error: `SPFN_AUTH_SESSION_SECRET has low entropy (${entropy.toFixed(2)} bits/char, minimum 3.5). Use a more random secret.`,
|
|
108
|
+
details: { length, uniqueChars, entropy }
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
valid: true,
|
|
113
|
+
details: { length, uniqueChars, entropy }
|
|
114
|
+
};
|
|
115
|
+
} catch (err) {
|
|
116
|
+
return { valid: false, error: "Failed to validate SPFN_AUTH_SESSION_SECRET" };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export {
|
|
120
|
+
getSessionInfo,
|
|
121
|
+
sealSession,
|
|
122
|
+
shouldRefreshSession,
|
|
123
|
+
unsealSession,
|
|
124
|
+
validateSessionSecret
|
|
125
|
+
};
|
|
126
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/session.ts"],"sourcesContent":["/**\n * @spfn/auth - Client Session Management\n *\n * Uses Jose JWE (JSON Web Encryption) to securely store session data in cookies\n * More efficient than Iron Session with better Edge Runtime support\n */\n\nimport * as jose from 'jose';\n\nexport interface SessionData\n{\n userId: string;\n privateKey: string; // Base64 encoded DER\n keyId: string;\n algorithm: 'ES256' | 'RS256';\n}\n\n/**\n * Calculate Shannon entropy of a string\n * Returns entropy in bits per character\n *\n * @param str - String to calculate entropy for\n * @returns Entropy value (0 to ~6.6 bits for printable ASCII)\n */\nfunction calculateEntropy(str: string): number\n{\n const len = str.length;\n const frequencies = new Map<string, number>();\n\n // Count character frequencies\n for (const char of str)\n {\n frequencies.set(char, (frequencies.get(char) || 0) + 1);\n }\n\n // Calculate Shannon entropy\n let entropy = 0;\n for (const count of frequencies.values())\n {\n const probability = count / len;\n entropy -= probability * Math.log2(probability);\n }\n\n return entropy;\n}\n\n/**\n * Get session secret from environment\n * Must be at least 32 characters (256-bit)\n *\n * Derives a 32-byte key using SHA-256 to ensure compatibility with Jose A256GCM\n */\nasync function getSessionSecret(): Promise<Uint8Array>\n{\n const secret =\n process.env.SPFN_AUTH_SESSION_SECRET || // New prefixed version (recommended)\n process.env.SESSION_SECRET; // Legacy fallback\n\n if (!secret)\n {\n throw new Error('SPFN_AUTH_SESSION_SECRET environment variable is not set');\n }\n\n if (secret.length < 32)\n {\n throw new Error('SPFN_AUTH_SESSION_SECRET must be at least 32 characters long');\n }\n\n // Derive a 32-byte key using SHA-256 for A256GCM compatibility\n // Use Web Crypto API for universal compatibility (browser + Node.js)\n const encoder = new TextEncoder();\n const data = encoder.encode(secret);\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n return new Uint8Array(hashBuffer);\n}\n\n/**\n * Seal session data into encrypted JWT (JWE)\n *\n * @param data - Session data to encrypt\n * @param ttl - Time to live in seconds (default: 7 days)\n * @returns Encrypted JWT string\n */\nexport async function sealSession(\n data: SessionData,\n ttl: number = 60 * 60 * 24 * 7 // 7 days\n): Promise<string>\n{\n const secret = await getSessionSecret();\n\n return await new jose.EncryptJWT({ data })\n .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })\n .setIssuedAt()\n .setExpirationTime(`${ttl}s`)\n .setIssuer('spfn-auth')\n .setAudience('spfn-client')\n .encrypt(secret);\n}\n\n/**\n * Unseal encrypted JWT (JWE) to session data\n *\n * @param jwt - Encrypted JWT string\n * @returns Session data\n * @throws Error if session is invalid or expired\n */\nexport async function unsealSession(jwt: string): Promise<SessionData>\n{\n const secret = await getSessionSecret();\n\n try\n {\n const { payload } = await jose.jwtDecrypt(jwt, secret, {\n issuer: 'spfn-auth',\n audience: 'spfn-client',\n });\n\n return payload.data as SessionData;\n }\n catch (err)\n {\n if (err instanceof jose.errors.JWTExpired)\n {\n throw new Error('Session expired');\n }\n\n if (err instanceof jose.errors.JWEDecryptionFailed)\n {\n throw new Error('Invalid session');\n }\n\n if (err instanceof jose.errors.JWTClaimValidationFailed)\n {\n throw new Error('Session validation failed');\n }\n\n throw new Error('Failed to unseal session');\n }\n}\n\n/**\n * Get session metadata without decrypting\n *\n * @param jwt - Encrypted JWT string\n * @returns Session metadata or null if invalid\n */\nexport async function getSessionInfo(jwt: string): Promise<{\n issuedAt: Date;\n expiresAt: Date;\n issuer: string;\n audience: string;\n} | null>\n{\n const secret = await getSessionSecret();\n\n try\n {\n const { payload } = await jose.jwtDecrypt(jwt, secret);\n\n return {\n issuedAt: new Date(payload.iat! * 1000),\n expiresAt: new Date(payload.exp! * 1000),\n issuer: payload.iss || '',\n audience: Array.isArray(payload.aud) ? payload.aud[0] : payload.aud || '',\n };\n }\n catch (err)\n {\n // Log error for debugging but return null for graceful handling\n if (process.env.NODE_ENV !== 'production')\n {\n console.warn('[Session] Failed to get session info:', err instanceof Error ? err.message : 'Unknown error');\n }\n return null;\n }\n}\n\n/**\n * Check if session is about to expire (within threshold)\n *\n * @param jwt - Encrypted JWT string\n * @param thresholdHours - Hours before expiry to trigger refresh (default: 24)\n * @returns True if session should be refreshed\n */\nexport async function shouldRefreshSession(\n jwt: string,\n thresholdHours: number = 24\n): Promise<boolean>\n{\n const info = await getSessionInfo(jwt);\n\n if (!info)\n {\n return true;\n }\n\n const hoursRemaining = (info.expiresAt.getTime() - Date.now()) / (1000 * 60 * 60);\n\n return hoursRemaining < thresholdHours;\n}\n\n/**\n * Validate session secret strength\n * Call this at startup to ensure proper configuration\n *\n * Validation criteria:\n * - Minimum 32 characters (256-bit)\n * - Minimum 16 unique characters\n * - Minimum 3.5 bits/char Shannon entropy (good randomness)\n */\nexport function validateSessionSecret(): {\n valid: boolean;\n error?: string;\n details?: {\n length: number;\n uniqueChars: number;\n entropy: number;\n };\n}\n{\n try\n {\n const secret =\n process.env.SPFN_AUTH_SESSION_SECRET || // New prefixed version (recommended)\n process.env.SESSION_SECRET; // Legacy fallback\n\n if (!secret)\n {\n return { valid: false, error: 'SPFN_AUTH_SESSION_SECRET is not set' };\n }\n\n const length = secret.length;\n const uniqueChars = new Set(secret).size;\n const entropy = calculateEntropy(secret);\n\n // Check length (minimum 32 chars for 256-bit)\n if (length < 32)\n {\n return {\n valid: false,\n error: `SPFN_AUTH_SESSION_SECRET too short (${length} chars, minimum 32)`,\n details: { length, uniqueChars, entropy },\n };\n }\n\n // Check unique character diversity\n if (uniqueChars < 16)\n {\n return {\n valid: false,\n error: `SPFN_AUTH_SESSION_SECRET has low diversity (${uniqueChars} unique chars, minimum 16)`,\n details: { length, uniqueChars, entropy },\n };\n }\n\n // Check Shannon entropy (3.5 bits/char is good randomness)\n // For reference:\n // - Random lowercase: ~4.7 bits/char\n // - Random alphanumeric: ~5.2 bits/char\n // - Random printable ASCII: ~6.6 bits/char\n // - \"aaaaaaa...\": ~0 bits/char\n // - \"abcabcabc...\": ~1.58 bits/char\n if (entropy < 3.5)\n {\n return {\n valid: false,\n error: `SPFN_AUTH_SESSION_SECRET has low entropy (${entropy.toFixed(2)} bits/char, minimum 3.5). Use a more random secret.`,\n details: { length, uniqueChars, entropy },\n };\n }\n\n return {\n valid: true,\n details: { length, uniqueChars, entropy },\n };\n }\n catch (err)\n {\n return { valid: false, error: 'Failed to validate SPFN_AUTH_SESSION_SECRET' };\n }\n}"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @spfn/auth - API Response Types
|
|
3
|
+
*
|
|
4
|
+
* Auth-specific types for API endpoints
|
|
5
|
+
* For standard ApiResponse type, import from '@spfn/core/types/api-response'
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Session types
|
|
9
|
+
*/
|
|
10
|
+
interface SessionPayload {
|
|
11
|
+
userId: string;
|
|
12
|
+
role?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* RBAC types
|
|
16
|
+
*/
|
|
17
|
+
interface Permission {
|
|
18
|
+
resource: string;
|
|
19
|
+
action: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* API Response Types for specific endpoints
|
|
23
|
+
*/
|
|
24
|
+
interface CheckAccountExistsData {
|
|
25
|
+
exists: boolean;
|
|
26
|
+
identifier: string;
|
|
27
|
+
identifierType: 'email' | 'phone';
|
|
28
|
+
}
|
|
29
|
+
interface LoginData {
|
|
30
|
+
token: string;
|
|
31
|
+
user: {
|
|
32
|
+
id: string;
|
|
33
|
+
email?: string;
|
|
34
|
+
phone?: string;
|
|
35
|
+
role: string;
|
|
36
|
+
emailVerifiedAt?: string;
|
|
37
|
+
phoneVerifiedAt?: string;
|
|
38
|
+
};
|
|
39
|
+
passwordChangeRequired: boolean;
|
|
40
|
+
}
|
|
41
|
+
interface ChangePasswordData {
|
|
42
|
+
success: boolean;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type { ChangePasswordData, CheckAccountExistsData, LoginData, Permission, SessionPayload };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|