humankey 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,134 @@
1
+ import { AuthenticatorTransportFuture, RegistrationResponseJSON, CredentialDeviceType, AuthenticationResponseJSON } from '@simplewebauthn/server';
2
+
3
+ /** The action the user is approving */
4
+ interface ActionPayload {
5
+ /** Unique action type identifier, e.g. "send-message", "approve-transfer" */
6
+ action: string;
7
+ /** Arbitrary data that gets hashed into the challenge. Supports nested objects and arrays. */
8
+ data: Record<string, unknown>;
9
+ }
10
+ /** Output of createConfirmation() — contains the code the user must type */
11
+ interface Confirmation {
12
+ /** 4-character alphanumeric code derived from the action hash */
13
+ code: string;
14
+ /** The SHA-256 hash of the canonical action JSON (base64url) */
15
+ actionHash: string;
16
+ }
17
+ /** Input for requestTap() */
18
+ interface TapRequest {
19
+ /** Server-generated challenge (base64url) */
20
+ challenge: string;
21
+ /** The action being approved */
22
+ action: ActionPayload;
23
+ /** Confirmation from createConfirmation() */
24
+ confirmation: Confirmation;
25
+ /** What the user actually typed as their confirmation code */
26
+ userInput: string;
27
+ /** Credential IDs the user can authenticate with */
28
+ allowCredentials: Array<{
29
+ id: string;
30
+ transports?: AuthenticatorTransportFuture[];
31
+ }>;
32
+ /** Relying party ID, e.g. "example.com" */
33
+ rpID: string;
34
+ /** User verification requirement (default: 'required') */
35
+ userVerification?: UserVerificationRequirement;
36
+ /** Timeout in ms (default: 60000) */
37
+ timeout?: number;
38
+ }
39
+ /** The signed proof returned by requestTap() — send this to your server */
40
+ interface TapProof {
41
+ /** The raw WebAuthn authentication response */
42
+ response: AuthenticationResponseJSON;
43
+ /** The action that was approved */
44
+ action: ActionPayload;
45
+ /** The action hash that was signed (base64url) */
46
+ actionHash: string;
47
+ /** The confirmation hash that was signed (base64url) */
48
+ confirmationHash: string;
49
+ /** The user's confirmation input */
50
+ userInput: string;
51
+ }
52
+ /** Input for registerKey() */
53
+ interface RegisterKeyRequest {
54
+ /** Server-generated challenge (base64url) */
55
+ challenge: string;
56
+ /** Relying party ID */
57
+ rpID: string;
58
+ /** Relying party display name */
59
+ rpName: string;
60
+ /** Username for this credential */
61
+ userName: string;
62
+ /** Display name (defaults to userName) */
63
+ userDisplayName?: string;
64
+ /** Credential IDs to exclude (already registered) */
65
+ excludeCredentials?: Array<{
66
+ id: string;
67
+ transports?: AuthenticatorTransportFuture[];
68
+ }>;
69
+ /** Attestation type (default: 'direct' — verifies real hardware key) */
70
+ attestation?: AttestationConveyancePreference;
71
+ /** User verification requirement (default: 'required') */
72
+ userVerification?: UserVerificationRequirement;
73
+ /** Timeout in ms (default: 60000) */
74
+ timeout?: number;
75
+ }
76
+ /** A registered credential — store this server-side */
77
+ interface TapCredential {
78
+ /** Base64url credential ID */
79
+ id: string;
80
+ /** The credential public key bytes */
81
+ publicKey: Uint8Array;
82
+ /** Signature counter for replay detection */
83
+ counter: number;
84
+ /** Transports the authenticator supports */
85
+ transports?: AuthenticatorTransportFuture[];
86
+ /** Single-device or multi-device credential */
87
+ deviceType: CredentialDeviceType;
88
+ /** Whether the credential is backed up */
89
+ backedUp: boolean;
90
+ /** Authenticator AAGUID — identifies the make/model of the hardware key */
91
+ aaguid: string;
92
+ }
93
+ /** Result of registerKey() — send the response to your server for verification */
94
+ interface RegistrationResult {
95
+ /** Base64url credential ID */
96
+ credentialId: string;
97
+ /** The raw registration response — send to your server for verifyRegistration() */
98
+ response: RegistrationResponseJSON;
99
+ /** Transports the authenticator supports */
100
+ transports?: AuthenticatorTransportFuture[];
101
+ }
102
+ /** Input for verifyTapProof() */
103
+ interface VerifyTapProofRequest {
104
+ /** The TapProof from the client */
105
+ proof: TapProof;
106
+ /** The stored credential for this user */
107
+ credential: TapCredential;
108
+ /** The challenge you generated server-side (base64url) */
109
+ expectedChallenge: string;
110
+ /** Your server's copy of the action (used to re-derive hashes) */
111
+ expectedAction: ActionPayload;
112
+ /** Expected origin(s), e.g. "https://example.com" */
113
+ expectedOrigin: string | string[];
114
+ /** Expected relying party ID */
115
+ expectedRPID: string;
116
+ /** Require user verification (default: true) */
117
+ requireUserVerification?: boolean;
118
+ /** When true (default), throw CONFIRMATION_MISMATCH if the user typed the wrong code.
119
+ * Set to false to handle confirmation validation manually via result.confirmationValid. */
120
+ requireConfirmation?: boolean;
121
+ }
122
+ /** Result of verifyTapProof() */
123
+ interface VerifyResult {
124
+ /** Overall verification passed */
125
+ verified: boolean;
126
+ /** User verification (biometric/PIN) was performed */
127
+ userVerified: boolean;
128
+ /** User typed the correct confirmation code for this action */
129
+ confirmationValid: boolean;
130
+ /** Updated signature counter — store this */
131
+ newCounter: number;
132
+ }
133
+
134
+ export type { ActionPayload as A, Confirmation as C, RegisterKeyRequest as R, TapRequest as T, VerifyResult as V, TapProof as a, RegistrationResult as b, TapCredential as c, VerifyTapProofRequest as d };
@@ -0,0 +1,14 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+ var _chunkFW3YUVJCcjs = require('./chunk-FW3YUVJC.cjs');
6
+
7
+
8
+ var _chunkJI6NIMGKcjs = require('./chunk-JI6NIMGK.cjs');
9
+
10
+
11
+
12
+
13
+
14
+ exports.HumanKeyError = _chunkJI6NIMGKcjs.HumanKeyError; exports.createChallenge = _chunkFW3YUVJCcjs.createChallenge; exports.verifyRegistration = _chunkFW3YUVJCcjs.verifyRegistration; exports.verifyTapProof = _chunkFW3YUVJCcjs.verifyTapProof;
@@ -0,0 +1,59 @@
1
+ import { c as TapCredential, d as VerifyTapProofRequest, V as VerifyResult } from './types-By44RNIt.cjs';
2
+ export { A as ActionPayload, a as TapProof } from './types-By44RNIt.cjs';
3
+ export { H as HumanKeyError, a as HumanKeyErrorCode } from './errors-BmtCXo7w.cjs';
4
+ import { RegistrationResponseJSON } from '@simplewebauthn/server';
5
+ export { RegistrationResponseJSON } from '@simplewebauthn/server';
6
+
7
+ /**
8
+ * Generate a cryptographically random challenge string (base64url).
9
+ * Use this server-side to create challenges for registration and tap flows.
10
+ *
11
+ * @param byteLength Number of random bytes (default: 32, producing a 256-bit challenge)
12
+ * @returns A base64url-encoded random challenge string
13
+ */
14
+ declare function createChallenge(byteLength?: number): string;
15
+
16
+ /** Input for verifyRegistration() */
17
+ interface VerifyRegistrationRequest {
18
+ /** The registration response from the client */
19
+ response: RegistrationResponseJSON;
20
+ /** The challenge you generated server-side (base64url) */
21
+ expectedChallenge: string;
22
+ /** Expected origin(s), e.g. "https://example.com" */
23
+ expectedOrigin: string | string[];
24
+ /** Expected relying party ID */
25
+ expectedRPID?: string | string[];
26
+ /** Require user verification (default: true) */
27
+ requireUserVerification?: boolean;
28
+ /** Restrict registration to specific authenticator models by AAGUID.
29
+ * When set, only authenticators with a matching AAGUID are accepted. */
30
+ allowedAAGUIDs?: string[];
31
+ }
32
+ /** Result of verifyRegistration() */
33
+ interface VerifyRegistrationResult {
34
+ /** The verified credential — store this server-side */
35
+ credential: TapCredential;
36
+ /** Whether the registration was verified */
37
+ verified: boolean;
38
+ }
39
+ /**
40
+ * Verify a registration response on the server and extract the credential.
41
+ * Wraps @simplewebauthn/server's verifyRegistrationResponse and returns
42
+ * a TapCredential ready for storage.
43
+ */
44
+ declare function verifyRegistration(request: VerifyRegistrationRequest): Promise<VerifyRegistrationResult>;
45
+
46
+ /**
47
+ * Verify a TapProof on the server.
48
+ * Re-derives all hashes from the server's copy of the action to ensure integrity.
49
+ *
50
+ * Checks:
51
+ * 1. Action hash matches (client didn't tamper with the action)
52
+ * 2. Confirmation code is valid for this action
53
+ * 3. WebAuthn signature is valid
54
+ * 4. User verification flag is set (independent of browser claim)
55
+ * 5. Signature counter increased (replay protection)
56
+ */
57
+ declare function verifyTapProof(request: VerifyTapProofRequest): Promise<VerifyResult>;
58
+
59
+ export { TapCredential, type VerifyRegistrationRequest, type VerifyRegistrationResult, VerifyResult, VerifyTapProofRequest, createChallenge, verifyRegistration, verifyTapProof };
@@ -0,0 +1,59 @@
1
+ import { c as TapCredential, d as VerifyTapProofRequest, V as VerifyResult } from './types-By44RNIt.js';
2
+ export { A as ActionPayload, a as TapProof } from './types-By44RNIt.js';
3
+ export { H as HumanKeyError, a as HumanKeyErrorCode } from './errors-BmtCXo7w.js';
4
+ import { RegistrationResponseJSON } from '@simplewebauthn/server';
5
+ export { RegistrationResponseJSON } from '@simplewebauthn/server';
6
+
7
+ /**
8
+ * Generate a cryptographically random challenge string (base64url).
9
+ * Use this server-side to create challenges for registration and tap flows.
10
+ *
11
+ * @param byteLength Number of random bytes (default: 32, producing a 256-bit challenge)
12
+ * @returns A base64url-encoded random challenge string
13
+ */
14
+ declare function createChallenge(byteLength?: number): string;
15
+
16
+ /** Input for verifyRegistration() */
17
+ interface VerifyRegistrationRequest {
18
+ /** The registration response from the client */
19
+ response: RegistrationResponseJSON;
20
+ /** The challenge you generated server-side (base64url) */
21
+ expectedChallenge: string;
22
+ /** Expected origin(s), e.g. "https://example.com" */
23
+ expectedOrigin: string | string[];
24
+ /** Expected relying party ID */
25
+ expectedRPID?: string | string[];
26
+ /** Require user verification (default: true) */
27
+ requireUserVerification?: boolean;
28
+ /** Restrict registration to specific authenticator models by AAGUID.
29
+ * When set, only authenticators with a matching AAGUID are accepted. */
30
+ allowedAAGUIDs?: string[];
31
+ }
32
+ /** Result of verifyRegistration() */
33
+ interface VerifyRegistrationResult {
34
+ /** The verified credential — store this server-side */
35
+ credential: TapCredential;
36
+ /** Whether the registration was verified */
37
+ verified: boolean;
38
+ }
39
+ /**
40
+ * Verify a registration response on the server and extract the credential.
41
+ * Wraps @simplewebauthn/server's verifyRegistrationResponse and returns
42
+ * a TapCredential ready for storage.
43
+ */
44
+ declare function verifyRegistration(request: VerifyRegistrationRequest): Promise<VerifyRegistrationResult>;
45
+
46
+ /**
47
+ * Verify a TapProof on the server.
48
+ * Re-derives all hashes from the server's copy of the action to ensure integrity.
49
+ *
50
+ * Checks:
51
+ * 1. Action hash matches (client didn't tamper with the action)
52
+ * 2. Confirmation code is valid for this action
53
+ * 3. WebAuthn signature is valid
54
+ * 4. User verification flag is set (independent of browser claim)
55
+ * 5. Signature counter increased (replay protection)
56
+ */
57
+ declare function verifyTapProof(request: VerifyTapProofRequest): Promise<VerifyResult>;
58
+
59
+ export { TapCredential, type VerifyRegistrationRequest, type VerifyRegistrationResult, VerifyResult, VerifyTapProofRequest, createChallenge, verifyRegistration, verifyTapProof };
@@ -0,0 +1,14 @@
1
+ import {
2
+ createChallenge,
3
+ verifyRegistration,
4
+ verifyTapProof
5
+ } from "./chunk-XXJAJHNP.mjs";
6
+ import {
7
+ HumanKeyError
8
+ } from "./chunk-CLQSCDXC.mjs";
9
+ export {
10
+ HumanKeyError,
11
+ createChallenge,
12
+ verifyRegistration,
13
+ verifyTapProof
14
+ };
package/package.json ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "humankey",
3
+ "version": "0.2.0",
4
+ "description": "Per-action hardware key (YubiKey/FIDO2) verification SDK with built-in confirmation step",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "import": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.mjs"
11
+ },
12
+ "require": {
13
+ "types": "./dist/index.d.cts",
14
+ "default": "./dist/index.cjs"
15
+ }
16
+ },
17
+ "./verify": {
18
+ "import": {
19
+ "types": "./dist/verify.d.ts",
20
+ "default": "./dist/verify.mjs"
21
+ },
22
+ "require": {
23
+ "types": "./dist/verify.d.cts",
24
+ "default": "./dist/verify.cjs"
25
+ }
26
+ },
27
+ "./express": {
28
+ "import": {
29
+ "types": "./dist/express.d.ts",
30
+ "default": "./dist/express.mjs"
31
+ },
32
+ "require": {
33
+ "types": "./dist/express.d.cts",
34
+ "default": "./dist/express.cjs"
35
+ }
36
+ }
37
+ },
38
+ "files": [
39
+ "dist",
40
+ "README.md",
41
+ "LICENSE"
42
+ ],
43
+ "scripts": {
44
+ "build": "tsup",
45
+ "dev": "tsup --watch",
46
+ "test": "vitest run",
47
+ "test:watch": "vitest",
48
+ "typecheck": "tsc --noEmit",
49
+ "prepublishOnly": "npm run build"
50
+ },
51
+ "keywords": [
52
+ "webauthn",
53
+ "fido2",
54
+ "yubikey",
55
+ "hardware-key",
56
+ "authentication",
57
+ "human-verification",
58
+ "per-action",
59
+ "security"
60
+ ],
61
+ "license": "MIT",
62
+ "dependencies": {
63
+ "@simplewebauthn/server": "^13.3.0"
64
+ },
65
+ "peerDependencies": {
66
+ "@simplewebauthn/browser": "^13.3.0",
67
+ "express": "^4.18.0 || ^5.0.0"
68
+ },
69
+ "peerDependenciesMeta": {
70
+ "@simplewebauthn/browser": {
71
+ "optional": true
72
+ },
73
+ "express": {
74
+ "optional": true
75
+ }
76
+ },
77
+ "devDependencies": {
78
+ "@simplewebauthn/browser": "^13.3.0",
79
+ "@types/express": "^5.0.6",
80
+ "@types/supertest": "^7.2.0",
81
+ "express": "^5.2.1",
82
+ "supertest": "^7.2.2",
83
+ "tsup": "^8.0.0",
84
+ "typescript": "^5.7.0",
85
+ "vitest": "^3.0.0"
86
+ },
87
+ "engines": {
88
+ "node": ">=20.0.0"
89
+ }
90
+ }