@passkeykit/server 2.0.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/challenge-token.d.ts +36 -0
- package/dist/challenge-token.js +74 -0
- package/dist/esm/challenge-token.js +70 -0
- package/dist/esm/express-routes.js +127 -0
- package/dist/esm/index.js +18 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/passkey-server.js +241 -0
- package/dist/esm/password-argon2.js +30 -0
- package/dist/esm/password.js +81 -0
- package/dist/esm/stores.js +147 -0
- package/dist/esm/types.js +8 -0
- package/dist/express-routes.d.ts +43 -0
- package/dist/express-routes.js +130 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +31 -0
- package/dist/passkey-server.d.ts +80 -0
- package/dist/passkey-server.js +245 -0
- package/dist/password-argon2.d.ts +22 -0
- package/dist/password-argon2.js +38 -0
- package/dist/password.d.ts +34 -0
- package/dist/password.js +86 -0
- package/dist/stores.d.ts +50 -0
- package/dist/stores.js +154 -0
- package/dist/types.d.ts +103 -0
- package/dist/types.js +9 -0
- package/package.json +62 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for passkey-kit-server
|
|
3
|
+
*
|
|
4
|
+
* @ai_context These types define the storage interface abstraction.
|
|
5
|
+
* Apps provide their own ChallengeStore and CredentialStore implementations
|
|
6
|
+
* so the library works with any backend (Firestore, file JSON, SQLite, etc).
|
|
7
|
+
*/
|
|
8
|
+
import type { AuthenticatorTransportFuture } from '@simplewebauthn/server';
|
|
9
|
+
/** Configuration for PasskeyServer */
|
|
10
|
+
export interface PasskeyServerConfig {
|
|
11
|
+
/** Relying Party name shown to users (e.g. "MovieBox", "SafeHarbor") */
|
|
12
|
+
rpName: string;
|
|
13
|
+
/** Relying Party ID — must be a valid domain (e.g. "movies.danieltech.dev") */
|
|
14
|
+
rpId: string;
|
|
15
|
+
/** Allowed origins for WebAuthn (e.g. ["https://movies.danieltech.dev"]) */
|
|
16
|
+
allowedOrigins: string[];
|
|
17
|
+
/**
|
|
18
|
+
* Challenge store implementation (stateful mode).
|
|
19
|
+
* If omitted, stateless mode is used instead (requires `encryptionKey`).
|
|
20
|
+
*/
|
|
21
|
+
challengeStore?: ChallengeStore;
|
|
22
|
+
/** Credential store implementation */
|
|
23
|
+
credentialStore: CredentialStore;
|
|
24
|
+
/** Challenge TTL in ms (default: 5 minutes) */
|
|
25
|
+
challengeTTL?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Secret key for stateless challenge tokens (AES-256-GCM).
|
|
28
|
+
* Required when `challengeStore` is not provided.
|
|
29
|
+
* Must be at least 32 characters. Derive from env: process.env.PASSKEY_SECRET
|
|
30
|
+
*/
|
|
31
|
+
encryptionKey?: string;
|
|
32
|
+
}
|
|
33
|
+
/** A stored WebAuthn credential (persisted per-user) */
|
|
34
|
+
export interface StoredCredential {
|
|
35
|
+
/** Base64URL-encoded credential ID */
|
|
36
|
+
credentialId: string;
|
|
37
|
+
/** Base64URL-encoded public key */
|
|
38
|
+
publicKey: string;
|
|
39
|
+
/** Signature counter for replay protection */
|
|
40
|
+
counter: number;
|
|
41
|
+
/** Credential transports (for allowCredentials hints) */
|
|
42
|
+
transports?: AuthenticatorTransportFuture[];
|
|
43
|
+
/** Human-readable name for this credential */
|
|
44
|
+
name?: string;
|
|
45
|
+
/** ISO timestamp of registration */
|
|
46
|
+
registeredAt: string;
|
|
47
|
+
/** User ID this credential belongs to */
|
|
48
|
+
userId: string;
|
|
49
|
+
}
|
|
50
|
+
/** A stored challenge (short-lived, for verification) */
|
|
51
|
+
export interface StoredChallenge {
|
|
52
|
+
/** The challenge string */
|
|
53
|
+
challenge: string;
|
|
54
|
+
/** User ID (if applicable, e.g. during registration) */
|
|
55
|
+
userId?: string;
|
|
56
|
+
/** Expiry timestamp (ms since epoch) */
|
|
57
|
+
expiresAt: number;
|
|
58
|
+
/** 'registration' or 'authentication' */
|
|
59
|
+
type: 'registration' | 'authentication';
|
|
60
|
+
}
|
|
61
|
+
/** User info passed during registration */
|
|
62
|
+
export interface UserInfo {
|
|
63
|
+
id: string;
|
|
64
|
+
name: string;
|
|
65
|
+
displayName?: string;
|
|
66
|
+
}
|
|
67
|
+
/** Result of successful registration */
|
|
68
|
+
export interface RegistrationResult {
|
|
69
|
+
credential: StoredCredential;
|
|
70
|
+
verified: boolean;
|
|
71
|
+
}
|
|
72
|
+
/** Result of successful authentication */
|
|
73
|
+
export interface AuthenticationResult {
|
|
74
|
+
credentialId: string;
|
|
75
|
+
userId: string;
|
|
76
|
+
verified: boolean;
|
|
77
|
+
newCounter: number;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Challenge store abstraction — apps implement this for their storage backend.
|
|
81
|
+
* Challenges are short-lived (5 min default) and must be cleaned up.
|
|
82
|
+
*/
|
|
83
|
+
export interface ChallengeStore {
|
|
84
|
+
/** Save a challenge. Key can be any unique string (userId or random token). */
|
|
85
|
+
save(key: string, challenge: StoredChallenge): Promise<void>;
|
|
86
|
+
/** Retrieve and delete a challenge (one-time use). Returns null if expired/missing. */
|
|
87
|
+
consume(key: string): Promise<StoredChallenge | null>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Credential store abstraction — apps implement this for their storage backend.
|
|
91
|
+
*/
|
|
92
|
+
export interface CredentialStore {
|
|
93
|
+
/** Save a new credential */
|
|
94
|
+
save(credential: StoredCredential): Promise<void>;
|
|
95
|
+
/** Get all credentials for a user */
|
|
96
|
+
getByUserId(userId: string): Promise<StoredCredential[]>;
|
|
97
|
+
/** Get a credential by its ID */
|
|
98
|
+
getByCredentialId(credentialId: string): Promise<StoredCredential | null>;
|
|
99
|
+
/** Update counter after successful authentication */
|
|
100
|
+
updateCounter(credentialId: string, newCounter: number): Promise<void>;
|
|
101
|
+
/** Delete a credential */
|
|
102
|
+
delete(credentialId: string): Promise<void>;
|
|
103
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Type definitions for passkey-kit-server
|
|
4
|
+
*
|
|
5
|
+
* @ai_context These types define the storage interface abstraction.
|
|
6
|
+
* Apps provide their own ChallengeStore and CredentialStore implementations
|
|
7
|
+
* so the library works with any backend (Firestore, file JSON, SQLite, etc).
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@passkeykit/server",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Server-side WebAuthn passkey verification \u2014 stateless or stateful, pure JS, works on serverless",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/esm/index.js",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
},
|
|
14
|
+
"./express": {
|
|
15
|
+
"import": "./dist/esm/express-routes.js",
|
|
16
|
+
"require": "./dist/express-routes.js",
|
|
17
|
+
"types": "./dist/express-routes.d.ts"
|
|
18
|
+
},
|
|
19
|
+
"./argon2": {
|
|
20
|
+
"import": "./dist/esm/password-argon2.js",
|
|
21
|
+
"require": "./dist/password-argon2.js",
|
|
22
|
+
"types": "./dist/password-argon2.d.ts"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsc && tsc -p tsconfig.esm.json && echo '{\"type\":\"module\"}' > dist/esm/package.json",
|
|
30
|
+
"prepublishOnly": "npm run build"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"webauthn",
|
|
34
|
+
"passkey",
|
|
35
|
+
"fido2",
|
|
36
|
+
"authentication",
|
|
37
|
+
"serverless",
|
|
38
|
+
"scrypt"
|
|
39
|
+
],
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@simplewebauthn/server": "^13.1.1",
|
|
43
|
+
"@noble/hashes": "^1.7.0"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"express": "^4.0.0 || ^5.0.0",
|
|
47
|
+
"argon2": "^0.41.0"
|
|
48
|
+
},
|
|
49
|
+
"peerDependenciesMeta": {
|
|
50
|
+
"express": {
|
|
51
|
+
"optional": true
|
|
52
|
+
},
|
|
53
|
+
"argon2": {
|
|
54
|
+
"optional": true
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/express": "^5.0.0",
|
|
59
|
+
"@types/node": "^22.0.0",
|
|
60
|
+
"typescript": "^5.7.0"
|
|
61
|
+
}
|
|
62
|
+
}
|