@inai-dev/shared 1.5.0 → 1.7.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/dist/index.cjs +5 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -58,11 +58,13 @@ var InAIAuthError = class extends Error {
|
|
|
58
58
|
this.status = status;
|
|
59
59
|
const parsed = body;
|
|
60
60
|
this.body = {
|
|
61
|
-
|
|
61
|
+
type: parsed?.type ?? "UNKNOWN_ERROR",
|
|
62
|
+
title: parsed?.title ?? message,
|
|
63
|
+
status,
|
|
62
64
|
detail: parsed?.detail ?? message,
|
|
63
|
-
|
|
65
|
+
instance: parsed?.instance ?? void 0
|
|
64
66
|
};
|
|
65
|
-
this.code = this.body.
|
|
67
|
+
this.code = this.body.type;
|
|
66
68
|
}
|
|
67
69
|
};
|
|
68
70
|
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/jwt.ts","../src/jwks.ts","../src/constants.ts","../src/url.ts","../src/validators.ts"],"sourcesContent":["export { InAIAuthError } from \"./errors\";\nexport {\n decodeJWTPayload,\n isTokenExpired,\n getClaimsFromToken,\n decodeJWTHeader,\n verifyES256,\n importJWKPublicKey,\n} from \"./jwt\";\nexport { JWKSClient } from \"./jwks\";\nexport {\n COOKIE_AUTH_TOKEN,\n COOKIE_REFRESH_TOKEN,\n COOKIE_AUTH_SESSION,\n DEFAULT_SIGN_IN_URL,\n DEFAULT_SIGN_UP_URL,\n DEFAULT_AFTER_SIGN_IN_URL,\n DEFAULT_AFTER_SIGN_OUT_URL,\n HEADER_PUBLISHABLE_KEY,\n HEADER_AUTHORIZATION,\n HEADER_INAI_AUTH,\n DEFAULT_API_URL,\n DEFAULT_JWKS_URL,\n} from \"./constants\";\nexport { normalizeApiUrl, buildEndpoint } from \"./url\";\nexport { isValidEmail, isStrongPassword } from \"./validators\";\n","import type { InAIAuthErrorBody } from \"@inai-dev/types\";\n\nexport class InAIAuthError extends Error {\n status: number;\n body: InAIAuthErrorBody;\n code: string;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"InAIAuthError\";\n this.status = status;\n const parsed = body as Record<string, unknown> | null;\n this.body = {\n code: (parsed?.code as string) ?? \"UNKNOWN_ERROR\",\n detail: (parsed?.detail as string) ?? message,\n field: (parsed?.field as string) ?? undefined,\n };\n this.code = this.body.code;\n }\n}\n","import type { JWTClaims } from \"@inai-dev/types\";\n\nfunction base64urlDecode(str: string): Uint8Array {\n let padded = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const remainder = padded.length % 4;\n if (remainder === 1) throw new Error(\"Invalid base64url string\");\n if (remainder === 2) padded += \"==\";\n else if (remainder === 3) padded += \"=\";\n try {\n const binString = atob(padded);\n return Uint8Array.from(binString, (ch) => ch.charCodeAt(0));\n } catch {\n throw new Error(\"Invalid base64url encoding\");\n }\n}\n\nfunction base64urlToString(str: string): string {\n return new TextDecoder().decode(base64urlDecode(str));\n}\n\nexport function decodeJWTPayload(token: string): JWTClaims | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n return JSON.parse(base64urlToString(parts[1]));\n } catch {\n return null;\n }\n}\n\nexport function isTokenExpired(token: string): boolean {\n const claims = decodeJWTPayload(token);\n if (!claims?.exp) return true;\n return Date.now() >= claims.exp * 1000;\n}\n\nexport function getClaimsFromToken(token: string): JWTClaims | null {\n return decodeJWTPayload(token);\n}\n\nexport function decodeJWTHeader(token: string): { alg: string; kid: string; typ?: string } | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n return JSON.parse(base64urlToString(parts[0]));\n } catch {\n return null;\n }\n}\n\nexport async function importJWKPublicKey(jwk: JsonWebKey): Promise<CryptoKey> {\n return crypto.subtle.importKey(\n \"jwk\",\n jwk,\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n false,\n [\"verify\"],\n );\n}\n\nexport async function verifyES256(token: string, publicKey: CryptoKey): Promise<JWTClaims | null> {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n\n const [headerB64, payloadB64, signatureB64] = parts;\n\n const encoder = new TextEncoder();\n const signingInput = encoder.encode(`${headerB64}.${payloadB64}`);\n const signature = base64urlDecode(signatureB64);\n\n const valid = await crypto.subtle.verify(\n { name: \"ECDSA\", hash: \"SHA-256\" },\n publicKey,\n signature.buffer as ArrayBuffer,\n signingInput,\n );\n\n if (!valid) return null;\n\n const payloadJson = new TextDecoder().decode(base64urlDecode(payloadB64));\n const payload = JSON.parse(payloadJson) as JWTClaims;\n\n // Check expiration (required)\n if (!payload.exp || typeof payload.exp !== \"number\") {\n return null;\n }\n if (Date.now() >= payload.exp * 1000) {\n return null;\n }\n\n return payload;\n } catch {\n return null;\n }\n}\n","import { importJWKPublicKey } from \"./jwt\";\n\ninterface JWKSResponse {\n keys: Array<{\n kty: string;\n crv: string;\n kid: string;\n use: string;\n alg: string;\n x: string;\n y: string;\n }>;\n}\n\nexport class JWKSClient {\n private cache: Map<string, CryptoKey> = new Map();\n private rawKeys: Map<string, JsonWebKey> = new Map();\n private lastFetchedAt = 0;\n private lastAttemptedAt = 0;\n private pendingInvalidation = false;\n private jwksUrl: string;\n private cacheTTL: number;\n private minRefetchInterval: number;\n\n constructor(jwksUrl: string, cacheTTL = 5 * 60 * 1000, minRefetchInterval = 10_000) {\n this.jwksUrl = jwksUrl;\n this.cacheTTL = cacheTTL;\n this.minRefetchInterval = minRefetchInterval;\n }\n\n async getKey(kid: string): Promise<CryptoKey> {\n // Return from cache if fresh AND not invalidated\n if (this.isCacheFresh() && !this.pendingInvalidation) {\n const cached = this.cache.get(kid);\n if (cached) return cached;\n }\n\n // Only refetch if minRefetchInterval has passed since last attempt\n if (Date.now() - this.lastAttemptedAt >= this.minRefetchInterval) {\n await this.fetchKeys();\n this.pendingInvalidation = false;\n } else {\n // Can't refetch yet — drop the invalidation, use stale cache\n this.pendingInvalidation = false;\n }\n\n const key = this.cache.get(kid);\n if (key) return key;\n\n throw new Error(`Unknown key ID: ${kid}`);\n }\n\n private isCacheFresh(): boolean {\n return Date.now() - this.lastFetchedAt < this.cacheTTL;\n }\n\n private async fetchKeys(): Promise<void> {\n this.lastAttemptedAt = Date.now();\n const res = await fetch(this.jwksUrl);\n if (!res.ok) {\n throw new Error(`Failed to fetch JWKS: ${res.status}`);\n }\n\n const data = (await res.json()) as JWKSResponse;\n\n this.cache.clear();\n this.rawKeys.clear();\n\n for (const jwk of data.keys) {\n if (jwk.kty !== \"EC\" || jwk.crv !== \"P-256\" || jwk.alg !== \"ES256\") continue;\n\n const publicKeyJwk: JsonWebKey = {\n kty: jwk.kty,\n crv: jwk.crv,\n x: jwk.x,\n y: jwk.y,\n };\n\n const cryptoKey = await importJWKPublicKey(publicKeyJwk);\n this.cache.set(jwk.kid, cryptoKey);\n this.rawKeys.set(jwk.kid, publicKeyJwk);\n }\n\n this.lastFetchedAt = Date.now();\n }\n\n /** Mark cache as stale. Actual refetch respects minRefetchInterval to prevent DoS. */\n invalidate(): void {\n this.pendingInvalidation = true;\n }\n}\n","export const COOKIE_AUTH_TOKEN = \"auth_token\";\nexport const COOKIE_REFRESH_TOKEN = \"refresh_token\";\nexport const COOKIE_AUTH_SESSION = \"auth_session\";\n\nexport const DEFAULT_SIGN_IN_URL = \"/login\";\nexport const DEFAULT_SIGN_UP_URL = \"/register\";\nexport const DEFAULT_AFTER_SIGN_IN_URL = \"/\";\nexport const DEFAULT_AFTER_SIGN_OUT_URL = \"/login\";\n\nexport const HEADER_PUBLISHABLE_KEY = \"X-Publishable-Key\";\nexport const HEADER_AUTHORIZATION = \"Authorization\";\nexport const HEADER_INAI_AUTH = \"x-inai-auth\";\n\nexport const DEFAULT_API_URL = \"https://apiauth.inai.dev\";\nexport const DEFAULT_JWKS_URL = \"https://apiauth.inai.dev/.well-known/jwks.json\";\n","export function normalizeApiUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nexport function buildEndpoint(apiUrl: string, path: string): string {\n return `${normalizeApiUrl(apiUrl)}${path}`;\n}\n","export function isValidEmail(email: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n}\n\nexport function isStrongPassword(password: string): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n if (password.length < 8) errors.push(\"Password must be at least 8 characters\");\n if (!/[A-Z]/.test(password)) errors.push(\"Password must contain an uppercase letter\");\n if (!/[a-z]/.test(password)) errors.push(\"Password must contain a lowercase letter\");\n if (!/[0-9]/.test(password)) errors.push(\"Password must contain a number\");\n return { valid: errors.length === 0, errors };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/jwt.ts","../src/jwks.ts","../src/constants.ts","../src/url.ts","../src/validators.ts"],"sourcesContent":["export { InAIAuthError } from \"./errors\";\nexport {\n decodeJWTPayload,\n isTokenExpired,\n getClaimsFromToken,\n decodeJWTHeader,\n verifyES256,\n importJWKPublicKey,\n} from \"./jwt\";\nexport { JWKSClient } from \"./jwks\";\nexport {\n COOKIE_AUTH_TOKEN,\n COOKIE_REFRESH_TOKEN,\n COOKIE_AUTH_SESSION,\n DEFAULT_SIGN_IN_URL,\n DEFAULT_SIGN_UP_URL,\n DEFAULT_AFTER_SIGN_IN_URL,\n DEFAULT_AFTER_SIGN_OUT_URL,\n HEADER_PUBLISHABLE_KEY,\n HEADER_AUTHORIZATION,\n HEADER_INAI_AUTH,\n DEFAULT_API_URL,\n DEFAULT_JWKS_URL,\n} from \"./constants\";\nexport { normalizeApiUrl, buildEndpoint } from \"./url\";\nexport { isValidEmail, isStrongPassword } from \"./validators\";\n","import type { InAIAuthErrorBody } from \"@inai-dev/types\";\n\nexport class InAIAuthError extends Error {\n status: number;\n body: InAIAuthErrorBody;\n code: string;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"InAIAuthError\";\n this.status = status;\n const parsed = body as Record<string, unknown> | null;\n this.body = {\n type: (parsed?.type as string) ?? \"UNKNOWN_ERROR\",\n title: (parsed?.title as string) ?? message,\n status: status,\n detail: (parsed?.detail as string) ?? message,\n instance: (parsed?.instance as string) ?? undefined,\n };\n this.code = this.body.type;\n }\n}\n","import type { JWTClaims } from \"@inai-dev/types\";\n\nfunction base64urlDecode(str: string): Uint8Array {\n let padded = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const remainder = padded.length % 4;\n if (remainder === 1) throw new Error(\"Invalid base64url string\");\n if (remainder === 2) padded += \"==\";\n else if (remainder === 3) padded += \"=\";\n try {\n const binString = atob(padded);\n return Uint8Array.from(binString, (ch) => ch.charCodeAt(0));\n } catch {\n throw new Error(\"Invalid base64url encoding\");\n }\n}\n\nfunction base64urlToString(str: string): string {\n return new TextDecoder().decode(base64urlDecode(str));\n}\n\nexport function decodeJWTPayload(token: string): JWTClaims | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n return JSON.parse(base64urlToString(parts[1]));\n } catch {\n return null;\n }\n}\n\nexport function isTokenExpired(token: string): boolean {\n const claims = decodeJWTPayload(token);\n if (!claims?.exp) return true;\n return Date.now() >= claims.exp * 1000;\n}\n\nexport function getClaimsFromToken(token: string): JWTClaims | null {\n return decodeJWTPayload(token);\n}\n\nexport function decodeJWTHeader(token: string): { alg: string; kid: string; typ?: string } | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n return JSON.parse(base64urlToString(parts[0]));\n } catch {\n return null;\n }\n}\n\nexport async function importJWKPublicKey(jwk: JsonWebKey): Promise<CryptoKey> {\n return crypto.subtle.importKey(\n \"jwk\",\n jwk,\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n false,\n [\"verify\"],\n );\n}\n\nexport async function verifyES256(token: string, publicKey: CryptoKey): Promise<JWTClaims | null> {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n\n const [headerB64, payloadB64, signatureB64] = parts;\n\n const encoder = new TextEncoder();\n const signingInput = encoder.encode(`${headerB64}.${payloadB64}`);\n const signature = base64urlDecode(signatureB64);\n\n const valid = await crypto.subtle.verify(\n { name: \"ECDSA\", hash: \"SHA-256\" },\n publicKey,\n signature.buffer as ArrayBuffer,\n signingInput,\n );\n\n if (!valid) return null;\n\n const payloadJson = new TextDecoder().decode(base64urlDecode(payloadB64));\n const payload = JSON.parse(payloadJson) as JWTClaims;\n\n // Check expiration (required)\n if (!payload.exp || typeof payload.exp !== \"number\") {\n return null;\n }\n if (Date.now() >= payload.exp * 1000) {\n return null;\n }\n\n return payload;\n } catch {\n return null;\n }\n}\n","import { importJWKPublicKey } from \"./jwt\";\n\ninterface JWKSResponse {\n keys: Array<{\n kty: string;\n crv: string;\n kid: string;\n use: string;\n alg: string;\n x: string;\n y: string;\n }>;\n}\n\nexport class JWKSClient {\n private cache: Map<string, CryptoKey> = new Map();\n private rawKeys: Map<string, JsonWebKey> = new Map();\n private lastFetchedAt = 0;\n private lastAttemptedAt = 0;\n private pendingInvalidation = false;\n private jwksUrl: string;\n private cacheTTL: number;\n private minRefetchInterval: number;\n\n constructor(jwksUrl: string, cacheTTL = 5 * 60 * 1000, minRefetchInterval = 10_000) {\n this.jwksUrl = jwksUrl;\n this.cacheTTL = cacheTTL;\n this.minRefetchInterval = minRefetchInterval;\n }\n\n async getKey(kid: string): Promise<CryptoKey> {\n // Return from cache if fresh AND not invalidated\n if (this.isCacheFresh() && !this.pendingInvalidation) {\n const cached = this.cache.get(kid);\n if (cached) return cached;\n }\n\n // Only refetch if minRefetchInterval has passed since last attempt\n if (Date.now() - this.lastAttemptedAt >= this.minRefetchInterval) {\n await this.fetchKeys();\n this.pendingInvalidation = false;\n } else {\n // Can't refetch yet — drop the invalidation, use stale cache\n this.pendingInvalidation = false;\n }\n\n const key = this.cache.get(kid);\n if (key) return key;\n\n throw new Error(`Unknown key ID: ${kid}`);\n }\n\n private isCacheFresh(): boolean {\n return Date.now() - this.lastFetchedAt < this.cacheTTL;\n }\n\n private async fetchKeys(): Promise<void> {\n this.lastAttemptedAt = Date.now();\n const res = await fetch(this.jwksUrl);\n if (!res.ok) {\n throw new Error(`Failed to fetch JWKS: ${res.status}`);\n }\n\n const data = (await res.json()) as JWKSResponse;\n\n this.cache.clear();\n this.rawKeys.clear();\n\n for (const jwk of data.keys) {\n if (jwk.kty !== \"EC\" || jwk.crv !== \"P-256\" || jwk.alg !== \"ES256\") continue;\n\n const publicKeyJwk: JsonWebKey = {\n kty: jwk.kty,\n crv: jwk.crv,\n x: jwk.x,\n y: jwk.y,\n };\n\n const cryptoKey = await importJWKPublicKey(publicKeyJwk);\n this.cache.set(jwk.kid, cryptoKey);\n this.rawKeys.set(jwk.kid, publicKeyJwk);\n }\n\n this.lastFetchedAt = Date.now();\n }\n\n /** Mark cache as stale. Actual refetch respects minRefetchInterval to prevent DoS. */\n invalidate(): void {\n this.pendingInvalidation = true;\n }\n}\n","export const COOKIE_AUTH_TOKEN = \"auth_token\";\nexport const COOKIE_REFRESH_TOKEN = \"refresh_token\";\nexport const COOKIE_AUTH_SESSION = \"auth_session\";\n\nexport const DEFAULT_SIGN_IN_URL = \"/login\";\nexport const DEFAULT_SIGN_UP_URL = \"/register\";\nexport const DEFAULT_AFTER_SIGN_IN_URL = \"/\";\nexport const DEFAULT_AFTER_SIGN_OUT_URL = \"/login\";\n\nexport const HEADER_PUBLISHABLE_KEY = \"X-Publishable-Key\";\nexport const HEADER_AUTHORIZATION = \"Authorization\";\nexport const HEADER_INAI_AUTH = \"x-inai-auth\";\n\nexport const DEFAULT_API_URL = \"https://apiauth.inai.dev\";\nexport const DEFAULT_JWKS_URL = \"https://apiauth.inai.dev/.well-known/jwks.json\";\n","export function normalizeApiUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nexport function buildEndpoint(apiUrl: string, path: string): string {\n return `${normalizeApiUrl(apiUrl)}${path}`;\n}\n","export function isValidEmail(email: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n}\n\nexport function isStrongPassword(password: string): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n if (password.length < 8) errors.push(\"Password must be at least 8 characters\");\n if (!/[A-Z]/.test(password)) errors.push(\"Password must contain an uppercase letter\");\n if (!/[a-z]/.test(password)) errors.push(\"Password must contain a lowercase letter\");\n if (!/[0-9]/.test(password)) errors.push(\"Password must contain a number\");\n return { valid: errors.length === 0, errors };\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -9,11 +9,13 @@ var InAIAuthError = class extends Error {
|
|
|
9
9
|
this.status = status;
|
|
10
10
|
const parsed = body;
|
|
11
11
|
this.body = {
|
|
12
|
-
|
|
12
|
+
type: parsed?.type ?? "UNKNOWN_ERROR",
|
|
13
|
+
title: parsed?.title ?? message,
|
|
14
|
+
status,
|
|
13
15
|
detail: parsed?.detail ?? message,
|
|
14
|
-
|
|
16
|
+
instance: parsed?.instance ?? void 0
|
|
15
17
|
};
|
|
16
|
-
this.code = this.body.
|
|
18
|
+
this.code = this.body.type;
|
|
17
19
|
}
|
|
18
20
|
};
|
|
19
21
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/jwt.ts","../src/jwks.ts","../src/constants.ts","../src/url.ts","../src/validators.ts"],"sourcesContent":["import type { InAIAuthErrorBody } from \"@inai-dev/types\";\n\nexport class InAIAuthError extends Error {\n status: number;\n body: InAIAuthErrorBody;\n code: string;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"InAIAuthError\";\n this.status = status;\n const parsed = body as Record<string, unknown> | null;\n this.body = {\n code: (parsed?.code as string) ?? \"UNKNOWN_ERROR\",\n detail: (parsed?.detail as string) ?? message,\n field: (parsed?.field as string) ?? undefined,\n };\n this.code = this.body.code;\n }\n}\n","import type { JWTClaims } from \"@inai-dev/types\";\n\nfunction base64urlDecode(str: string): Uint8Array {\n let padded = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const remainder = padded.length % 4;\n if (remainder === 1) throw new Error(\"Invalid base64url string\");\n if (remainder === 2) padded += \"==\";\n else if (remainder === 3) padded += \"=\";\n try {\n const binString = atob(padded);\n return Uint8Array.from(binString, (ch) => ch.charCodeAt(0));\n } catch {\n throw new Error(\"Invalid base64url encoding\");\n }\n}\n\nfunction base64urlToString(str: string): string {\n return new TextDecoder().decode(base64urlDecode(str));\n}\n\nexport function decodeJWTPayload(token: string): JWTClaims | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n return JSON.parse(base64urlToString(parts[1]));\n } catch {\n return null;\n }\n}\n\nexport function isTokenExpired(token: string): boolean {\n const claims = decodeJWTPayload(token);\n if (!claims?.exp) return true;\n return Date.now() >= claims.exp * 1000;\n}\n\nexport function getClaimsFromToken(token: string): JWTClaims | null {\n return decodeJWTPayload(token);\n}\n\nexport function decodeJWTHeader(token: string): { alg: string; kid: string; typ?: string } | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n return JSON.parse(base64urlToString(parts[0]));\n } catch {\n return null;\n }\n}\n\nexport async function importJWKPublicKey(jwk: JsonWebKey): Promise<CryptoKey> {\n return crypto.subtle.importKey(\n \"jwk\",\n jwk,\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n false,\n [\"verify\"],\n );\n}\n\nexport async function verifyES256(token: string, publicKey: CryptoKey): Promise<JWTClaims | null> {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n\n const [headerB64, payloadB64, signatureB64] = parts;\n\n const encoder = new TextEncoder();\n const signingInput = encoder.encode(`${headerB64}.${payloadB64}`);\n const signature = base64urlDecode(signatureB64);\n\n const valid = await crypto.subtle.verify(\n { name: \"ECDSA\", hash: \"SHA-256\" },\n publicKey,\n signature.buffer as ArrayBuffer,\n signingInput,\n );\n\n if (!valid) return null;\n\n const payloadJson = new TextDecoder().decode(base64urlDecode(payloadB64));\n const payload = JSON.parse(payloadJson) as JWTClaims;\n\n // Check expiration (required)\n if (!payload.exp || typeof payload.exp !== \"number\") {\n return null;\n }\n if (Date.now() >= payload.exp * 1000) {\n return null;\n }\n\n return payload;\n } catch {\n return null;\n }\n}\n","import { importJWKPublicKey } from \"./jwt\";\n\ninterface JWKSResponse {\n keys: Array<{\n kty: string;\n crv: string;\n kid: string;\n use: string;\n alg: string;\n x: string;\n y: string;\n }>;\n}\n\nexport class JWKSClient {\n private cache: Map<string, CryptoKey> = new Map();\n private rawKeys: Map<string, JsonWebKey> = new Map();\n private lastFetchedAt = 0;\n private lastAttemptedAt = 0;\n private pendingInvalidation = false;\n private jwksUrl: string;\n private cacheTTL: number;\n private minRefetchInterval: number;\n\n constructor(jwksUrl: string, cacheTTL = 5 * 60 * 1000, minRefetchInterval = 10_000) {\n this.jwksUrl = jwksUrl;\n this.cacheTTL = cacheTTL;\n this.minRefetchInterval = minRefetchInterval;\n }\n\n async getKey(kid: string): Promise<CryptoKey> {\n // Return from cache if fresh AND not invalidated\n if (this.isCacheFresh() && !this.pendingInvalidation) {\n const cached = this.cache.get(kid);\n if (cached) return cached;\n }\n\n // Only refetch if minRefetchInterval has passed since last attempt\n if (Date.now() - this.lastAttemptedAt >= this.minRefetchInterval) {\n await this.fetchKeys();\n this.pendingInvalidation = false;\n } else {\n // Can't refetch yet — drop the invalidation, use stale cache\n this.pendingInvalidation = false;\n }\n\n const key = this.cache.get(kid);\n if (key) return key;\n\n throw new Error(`Unknown key ID: ${kid}`);\n }\n\n private isCacheFresh(): boolean {\n return Date.now() - this.lastFetchedAt < this.cacheTTL;\n }\n\n private async fetchKeys(): Promise<void> {\n this.lastAttemptedAt = Date.now();\n const res = await fetch(this.jwksUrl);\n if (!res.ok) {\n throw new Error(`Failed to fetch JWKS: ${res.status}`);\n }\n\n const data = (await res.json()) as JWKSResponse;\n\n this.cache.clear();\n this.rawKeys.clear();\n\n for (const jwk of data.keys) {\n if (jwk.kty !== \"EC\" || jwk.crv !== \"P-256\" || jwk.alg !== \"ES256\") continue;\n\n const publicKeyJwk: JsonWebKey = {\n kty: jwk.kty,\n crv: jwk.crv,\n x: jwk.x,\n y: jwk.y,\n };\n\n const cryptoKey = await importJWKPublicKey(publicKeyJwk);\n this.cache.set(jwk.kid, cryptoKey);\n this.rawKeys.set(jwk.kid, publicKeyJwk);\n }\n\n this.lastFetchedAt = Date.now();\n }\n\n /** Mark cache as stale. Actual refetch respects minRefetchInterval to prevent DoS. */\n invalidate(): void {\n this.pendingInvalidation = true;\n }\n}\n","export const COOKIE_AUTH_TOKEN = \"auth_token\";\nexport const COOKIE_REFRESH_TOKEN = \"refresh_token\";\nexport const COOKIE_AUTH_SESSION = \"auth_session\";\n\nexport const DEFAULT_SIGN_IN_URL = \"/login\";\nexport const DEFAULT_SIGN_UP_URL = \"/register\";\nexport const DEFAULT_AFTER_SIGN_IN_URL = \"/\";\nexport const DEFAULT_AFTER_SIGN_OUT_URL = \"/login\";\n\nexport const HEADER_PUBLISHABLE_KEY = \"X-Publishable-Key\";\nexport const HEADER_AUTHORIZATION = \"Authorization\";\nexport const HEADER_INAI_AUTH = \"x-inai-auth\";\n\nexport const DEFAULT_API_URL = \"https://apiauth.inai.dev\";\nexport const DEFAULT_JWKS_URL = \"https://apiauth.inai.dev/.well-known/jwks.json\";\n","export function normalizeApiUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nexport function buildEndpoint(apiUrl: string, path: string): string {\n return `${normalizeApiUrl(apiUrl)}${path}`;\n}\n","export function isValidEmail(email: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n}\n\nexport function isStrongPassword(password: string): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n if (password.length < 8) errors.push(\"Password must be at least 8 characters\");\n if (!/[A-Z]/.test(password)) errors.push(\"Password must contain an uppercase letter\");\n if (!/[a-z]/.test(password)) errors.push(\"Password must contain a lowercase letter\");\n if (!/[0-9]/.test(password)) errors.push(\"Password must contain a number\");\n return { valid: errors.length === 0, errors };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/jwt.ts","../src/jwks.ts","../src/constants.ts","../src/url.ts","../src/validators.ts"],"sourcesContent":["import type { InAIAuthErrorBody } from \"@inai-dev/types\";\n\nexport class InAIAuthError extends Error {\n status: number;\n body: InAIAuthErrorBody;\n code: string;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"InAIAuthError\";\n this.status = status;\n const parsed = body as Record<string, unknown> | null;\n this.body = {\n type: (parsed?.type as string) ?? \"UNKNOWN_ERROR\",\n title: (parsed?.title as string) ?? message,\n status: status,\n detail: (parsed?.detail as string) ?? message,\n instance: (parsed?.instance as string) ?? undefined,\n };\n this.code = this.body.type;\n }\n}\n","import type { JWTClaims } from \"@inai-dev/types\";\n\nfunction base64urlDecode(str: string): Uint8Array {\n let padded = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const remainder = padded.length % 4;\n if (remainder === 1) throw new Error(\"Invalid base64url string\");\n if (remainder === 2) padded += \"==\";\n else if (remainder === 3) padded += \"=\";\n try {\n const binString = atob(padded);\n return Uint8Array.from(binString, (ch) => ch.charCodeAt(0));\n } catch {\n throw new Error(\"Invalid base64url encoding\");\n }\n}\n\nfunction base64urlToString(str: string): string {\n return new TextDecoder().decode(base64urlDecode(str));\n}\n\nexport function decodeJWTPayload(token: string): JWTClaims | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n return JSON.parse(base64urlToString(parts[1]));\n } catch {\n return null;\n }\n}\n\nexport function isTokenExpired(token: string): boolean {\n const claims = decodeJWTPayload(token);\n if (!claims?.exp) return true;\n return Date.now() >= claims.exp * 1000;\n}\n\nexport function getClaimsFromToken(token: string): JWTClaims | null {\n return decodeJWTPayload(token);\n}\n\nexport function decodeJWTHeader(token: string): { alg: string; kid: string; typ?: string } | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n return JSON.parse(base64urlToString(parts[0]));\n } catch {\n return null;\n }\n}\n\nexport async function importJWKPublicKey(jwk: JsonWebKey): Promise<CryptoKey> {\n return crypto.subtle.importKey(\n \"jwk\",\n jwk,\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n false,\n [\"verify\"],\n );\n}\n\nexport async function verifyES256(token: string, publicKey: CryptoKey): Promise<JWTClaims | null> {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n\n const [headerB64, payloadB64, signatureB64] = parts;\n\n const encoder = new TextEncoder();\n const signingInput = encoder.encode(`${headerB64}.${payloadB64}`);\n const signature = base64urlDecode(signatureB64);\n\n const valid = await crypto.subtle.verify(\n { name: \"ECDSA\", hash: \"SHA-256\" },\n publicKey,\n signature.buffer as ArrayBuffer,\n signingInput,\n );\n\n if (!valid) return null;\n\n const payloadJson = new TextDecoder().decode(base64urlDecode(payloadB64));\n const payload = JSON.parse(payloadJson) as JWTClaims;\n\n // Check expiration (required)\n if (!payload.exp || typeof payload.exp !== \"number\") {\n return null;\n }\n if (Date.now() >= payload.exp * 1000) {\n return null;\n }\n\n return payload;\n } catch {\n return null;\n }\n}\n","import { importJWKPublicKey } from \"./jwt\";\n\ninterface JWKSResponse {\n keys: Array<{\n kty: string;\n crv: string;\n kid: string;\n use: string;\n alg: string;\n x: string;\n y: string;\n }>;\n}\n\nexport class JWKSClient {\n private cache: Map<string, CryptoKey> = new Map();\n private rawKeys: Map<string, JsonWebKey> = new Map();\n private lastFetchedAt = 0;\n private lastAttemptedAt = 0;\n private pendingInvalidation = false;\n private jwksUrl: string;\n private cacheTTL: number;\n private minRefetchInterval: number;\n\n constructor(jwksUrl: string, cacheTTL = 5 * 60 * 1000, minRefetchInterval = 10_000) {\n this.jwksUrl = jwksUrl;\n this.cacheTTL = cacheTTL;\n this.minRefetchInterval = minRefetchInterval;\n }\n\n async getKey(kid: string): Promise<CryptoKey> {\n // Return from cache if fresh AND not invalidated\n if (this.isCacheFresh() && !this.pendingInvalidation) {\n const cached = this.cache.get(kid);\n if (cached) return cached;\n }\n\n // Only refetch if minRefetchInterval has passed since last attempt\n if (Date.now() - this.lastAttemptedAt >= this.minRefetchInterval) {\n await this.fetchKeys();\n this.pendingInvalidation = false;\n } else {\n // Can't refetch yet — drop the invalidation, use stale cache\n this.pendingInvalidation = false;\n }\n\n const key = this.cache.get(kid);\n if (key) return key;\n\n throw new Error(`Unknown key ID: ${kid}`);\n }\n\n private isCacheFresh(): boolean {\n return Date.now() - this.lastFetchedAt < this.cacheTTL;\n }\n\n private async fetchKeys(): Promise<void> {\n this.lastAttemptedAt = Date.now();\n const res = await fetch(this.jwksUrl);\n if (!res.ok) {\n throw new Error(`Failed to fetch JWKS: ${res.status}`);\n }\n\n const data = (await res.json()) as JWKSResponse;\n\n this.cache.clear();\n this.rawKeys.clear();\n\n for (const jwk of data.keys) {\n if (jwk.kty !== \"EC\" || jwk.crv !== \"P-256\" || jwk.alg !== \"ES256\") continue;\n\n const publicKeyJwk: JsonWebKey = {\n kty: jwk.kty,\n crv: jwk.crv,\n x: jwk.x,\n y: jwk.y,\n };\n\n const cryptoKey = await importJWKPublicKey(publicKeyJwk);\n this.cache.set(jwk.kid, cryptoKey);\n this.rawKeys.set(jwk.kid, publicKeyJwk);\n }\n\n this.lastFetchedAt = Date.now();\n }\n\n /** Mark cache as stale. Actual refetch respects minRefetchInterval to prevent DoS. */\n invalidate(): void {\n this.pendingInvalidation = true;\n }\n}\n","export const COOKIE_AUTH_TOKEN = \"auth_token\";\nexport const COOKIE_REFRESH_TOKEN = \"refresh_token\";\nexport const COOKIE_AUTH_SESSION = \"auth_session\";\n\nexport const DEFAULT_SIGN_IN_URL = \"/login\";\nexport const DEFAULT_SIGN_UP_URL = \"/register\";\nexport const DEFAULT_AFTER_SIGN_IN_URL = \"/\";\nexport const DEFAULT_AFTER_SIGN_OUT_URL = \"/login\";\n\nexport const HEADER_PUBLISHABLE_KEY = \"X-Publishable-Key\";\nexport const HEADER_AUTHORIZATION = \"Authorization\";\nexport const HEADER_INAI_AUTH = \"x-inai-auth\";\n\nexport const DEFAULT_API_URL = \"https://apiauth.inai.dev\";\nexport const DEFAULT_JWKS_URL = \"https://apiauth.inai.dev/.well-known/jwks.json\";\n","export function normalizeApiUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nexport function buildEndpoint(apiUrl: string, path: string): string {\n return `${normalizeApiUrl(apiUrl)}${path}`;\n}\n","export function isValidEmail(email: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n}\n\nexport function isStrongPassword(password: string): {\n valid: boolean;\n errors: string[];\n} {\n const errors: string[] = [];\n if (password.length < 8) errors.push(\"Password must be at least 8 characters\");\n if (!/[A-Z]/.test(password)) errors.push(\"Password must contain an uppercase letter\");\n if (!/[a-z]/.test(password)) errors.push(\"Password must contain a lowercase letter\");\n if (!/[0-9]/.test(password)) errors.push(\"Password must contain a number\");\n return { valid: errors.length === 0, errors };\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inai-dev/shared",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Shared utilities for the InAI Auth SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"prepublishOnly": "npm run build"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@inai-dev/types": "^1.
|
|
27
|
+
"@inai-dev/types": "^1.7.0"
|
|
28
28
|
},
|
|
29
29
|
"sideEffects": false,
|
|
30
30
|
"publishConfig": {
|