humankey 0.2.0 → 0.3.1
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/README.md +165 -4
- package/dist/adapter-core-CFN3y3L0.d.ts +41 -0
- package/dist/adapter-core-CoBcSqdG.d.cts +41 -0
- package/dist/chunk-2KMBF2TH.cjs +27 -0
- package/dist/chunk-G2IT2ZP5.cjs +124 -0
- package/dist/chunk-G2X46ZRM.mjs +27 -0
- package/dist/chunk-RANGHXC7.mjs +75 -0
- package/dist/chunk-RQSBOE7B.cjs +76 -0
- package/dist/chunk-SZPXOH7Z.cjs +75 -0
- package/dist/chunk-U2AGXRNW.mjs +76 -0
- package/dist/chunk-Y6KQC7WK.mjs +124 -0
- package/dist/confirm-6RXLI2SS.cjs +9 -0
- package/dist/confirm-TSVTFC4N.mjs +9 -0
- package/dist/express.cjs +14 -102
- package/dist/express.d.cts +5 -38
- package/dist/express.d.ts +5 -38
- package/dist/express.mjs +17 -105
- package/dist/fastify.cjs +30 -0
- package/dist/fastify.d.cts +22 -0
- package/dist/fastify.d.ts +22 -0
- package/dist/fastify.mjs +30 -0
- package/dist/hono.cjs +35 -0
- package/dist/hono.d.cts +22 -0
- package/dist/hono.d.ts +22 -0
- package/dist/hono.mjs +35 -0
- package/dist/index.cjs +5 -144
- package/dist/index.mjs +10 -149
- package/dist/nextjs.cjs +40 -0
- package/dist/nextjs.d.cts +28 -0
- package/dist/nextjs.d.ts +28 -0
- package/dist/nextjs.mjs +40 -0
- package/dist/react.cjs +131 -0
- package/dist/react.d.cts +60 -0
- package/dist/react.d.ts +60 -0
- package/dist/react.mjs +131 -0
- package/dist/register-Y2ADAMHB.cjs +7 -0
- package/dist/register-ZGR2LHQ6.mjs +7 -0
- package/dist/tap-DJVQXGEJ.mjs +8 -0
- package/dist/tap-N5RN26H2.cjs +8 -0
- package/package.json +58 -2
package/dist/fastify.cjs
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
var _chunkG2IT2ZP5cjs = require('./chunk-G2IT2ZP5.cjs');
|
|
8
|
+
require('./chunk-FW3YUVJC.cjs');
|
|
9
|
+
require('./chunk-JI6NIMGK.cjs');
|
|
10
|
+
|
|
11
|
+
// src/fastify.ts
|
|
12
|
+
var humanKeyPlugin = async (fastify, config) => {
|
|
13
|
+
const resolved = _chunkG2IT2ZP5cjs.resolveConfig.call(void 0, config);
|
|
14
|
+
fastify.post("/challenge", async (_request, reply) => {
|
|
15
|
+
const result = await _chunkG2IT2ZP5cjs.handleChallenge.call(void 0, resolved);
|
|
16
|
+
return reply.status(result.status).send(result.body);
|
|
17
|
+
});
|
|
18
|
+
fastify.post("/register", async (request, reply) => {
|
|
19
|
+
const result = await _chunkG2IT2ZP5cjs.handleRegister.call(void 0, resolved, request.body);
|
|
20
|
+
return reply.status(result.status).send(result.body);
|
|
21
|
+
});
|
|
22
|
+
fastify.post("/verify", async (request, reply) => {
|
|
23
|
+
const result = await _chunkG2IT2ZP5cjs.handleVerify.call(void 0, resolved, request.body);
|
|
24
|
+
return reply.status(result.status).send(result.body);
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
exports.MemoryChallengeStore = _chunkG2IT2ZP5cjs.MemoryChallengeStore; exports.humanKeyPlugin = humanKeyPlugin;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { FastifyPluginAsync } from 'fastify';
|
|
2
|
+
import { H as HumanKeyAdapterConfig } from './adapter-core-CoBcSqdG.cjs';
|
|
3
|
+
export { C as ChallengeStore, M as MemoryChallengeStore } from './adapter-core-CoBcSqdG.cjs';
|
|
4
|
+
export { A as ActionPayload, c as TapCredential, V as VerifyResult } from './types-By44RNIt.cjs';
|
|
5
|
+
import '@simplewebauthn/server';
|
|
6
|
+
|
|
7
|
+
/** Configuration for the humankey Fastify plugin. */
|
|
8
|
+
type HumanKeyFastifyConfig = HumanKeyAdapterConfig;
|
|
9
|
+
/**
|
|
10
|
+
* Fastify plugin that registers humankey routes.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* ```ts
|
|
14
|
+
* import Fastify from 'fastify';
|
|
15
|
+
* import { humanKeyPlugin } from 'humankey/fastify';
|
|
16
|
+
* const app = Fastify();
|
|
17
|
+
* app.register(humanKeyPlugin, { prefix: '/api', ...config });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
declare const humanKeyPlugin: FastifyPluginAsync<HumanKeyFastifyConfig>;
|
|
21
|
+
|
|
22
|
+
export { type HumanKeyFastifyConfig, humanKeyPlugin };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { FastifyPluginAsync } from 'fastify';
|
|
2
|
+
import { H as HumanKeyAdapterConfig } from './adapter-core-CFN3y3L0.js';
|
|
3
|
+
export { C as ChallengeStore, M as MemoryChallengeStore } from './adapter-core-CFN3y3L0.js';
|
|
4
|
+
export { A as ActionPayload, c as TapCredential, V as VerifyResult } from './types-By44RNIt.js';
|
|
5
|
+
import '@simplewebauthn/server';
|
|
6
|
+
|
|
7
|
+
/** Configuration for the humankey Fastify plugin. */
|
|
8
|
+
type HumanKeyFastifyConfig = HumanKeyAdapterConfig;
|
|
9
|
+
/**
|
|
10
|
+
* Fastify plugin that registers humankey routes.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* ```ts
|
|
14
|
+
* import Fastify from 'fastify';
|
|
15
|
+
* import { humanKeyPlugin } from 'humankey/fastify';
|
|
16
|
+
* const app = Fastify();
|
|
17
|
+
* app.register(humanKeyPlugin, { prefix: '/api', ...config });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
declare const humanKeyPlugin: FastifyPluginAsync<HumanKeyFastifyConfig>;
|
|
21
|
+
|
|
22
|
+
export { type HumanKeyFastifyConfig, humanKeyPlugin };
|
package/dist/fastify.mjs
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MemoryChallengeStore,
|
|
3
|
+
handleChallenge,
|
|
4
|
+
handleRegister,
|
|
5
|
+
handleVerify,
|
|
6
|
+
resolveConfig
|
|
7
|
+
} from "./chunk-Y6KQC7WK.mjs";
|
|
8
|
+
import "./chunk-XXJAJHNP.mjs";
|
|
9
|
+
import "./chunk-CLQSCDXC.mjs";
|
|
10
|
+
|
|
11
|
+
// src/fastify.ts
|
|
12
|
+
var humanKeyPlugin = async (fastify, config) => {
|
|
13
|
+
const resolved = resolveConfig(config);
|
|
14
|
+
fastify.post("/challenge", async (_request, reply) => {
|
|
15
|
+
const result = await handleChallenge(resolved);
|
|
16
|
+
return reply.status(result.status).send(result.body);
|
|
17
|
+
});
|
|
18
|
+
fastify.post("/register", async (request, reply) => {
|
|
19
|
+
const result = await handleRegister(resolved, request.body);
|
|
20
|
+
return reply.status(result.status).send(result.body);
|
|
21
|
+
});
|
|
22
|
+
fastify.post("/verify", async (request, reply) => {
|
|
23
|
+
const result = await handleVerify(resolved, request.body);
|
|
24
|
+
return reply.status(result.status).send(result.body);
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
export {
|
|
28
|
+
MemoryChallengeStore,
|
|
29
|
+
humanKeyPlugin
|
|
30
|
+
};
|
package/dist/hono.cjs
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
var _chunkG2IT2ZP5cjs = require('./chunk-G2IT2ZP5.cjs');
|
|
8
|
+
require('./chunk-FW3YUVJC.cjs');
|
|
9
|
+
require('./chunk-JI6NIMGK.cjs');
|
|
10
|
+
|
|
11
|
+
// src/hono.ts
|
|
12
|
+
var _hono = require('hono');
|
|
13
|
+
function createHumanKeyApp(config) {
|
|
14
|
+
const resolved = _chunkG2IT2ZP5cjs.resolveConfig.call(void 0, config);
|
|
15
|
+
const app = new (0, _hono.Hono)();
|
|
16
|
+
app.post("/challenge", async (c) => {
|
|
17
|
+
const result = await _chunkG2IT2ZP5cjs.handleChallenge.call(void 0, resolved);
|
|
18
|
+
return c.json(result.body, result.status);
|
|
19
|
+
});
|
|
20
|
+
app.post("/register", async (c) => {
|
|
21
|
+
const body = await c.req.json();
|
|
22
|
+
const result = await _chunkG2IT2ZP5cjs.handleRegister.call(void 0, resolved, body);
|
|
23
|
+
return c.json(result.body, result.status);
|
|
24
|
+
});
|
|
25
|
+
app.post("/verify", async (c) => {
|
|
26
|
+
const body = await c.req.json();
|
|
27
|
+
const result = await _chunkG2IT2ZP5cjs.handleVerify.call(void 0, resolved, body);
|
|
28
|
+
return c.json(result.body, result.status);
|
|
29
|
+
});
|
|
30
|
+
return app;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
exports.MemoryChallengeStore = _chunkG2IT2ZP5cjs.MemoryChallengeStore; exports.createHumanKeyApp = createHumanKeyApp;
|
package/dist/hono.d.cts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { H as HumanKeyAdapterConfig } from './adapter-core-CoBcSqdG.cjs';
|
|
3
|
+
export { C as ChallengeStore, M as MemoryChallengeStore } from './adapter-core-CoBcSqdG.cjs';
|
|
4
|
+
export { A as ActionPayload, c as TapCredential, V as VerifyResult } from './types-By44RNIt.cjs';
|
|
5
|
+
import '@simplewebauthn/server';
|
|
6
|
+
|
|
7
|
+
/** Configuration for the humankey Hono adapter. */
|
|
8
|
+
type HumanKeyHonoConfig = HumanKeyAdapterConfig;
|
|
9
|
+
/**
|
|
10
|
+
* Create a Hono app with humankey routes.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { Hono } from 'hono';
|
|
15
|
+
* import { createHumanKeyApp } from 'humankey/hono';
|
|
16
|
+
* const app = new Hono();
|
|
17
|
+
* app.route('/api', createHumanKeyApp({ ... }));
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
declare function createHumanKeyApp(config: HumanKeyHonoConfig): Hono;
|
|
21
|
+
|
|
22
|
+
export { type HumanKeyHonoConfig, createHumanKeyApp };
|
package/dist/hono.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { H as HumanKeyAdapterConfig } from './adapter-core-CFN3y3L0.js';
|
|
3
|
+
export { C as ChallengeStore, M as MemoryChallengeStore } from './adapter-core-CFN3y3L0.js';
|
|
4
|
+
export { A as ActionPayload, c as TapCredential, V as VerifyResult } from './types-By44RNIt.js';
|
|
5
|
+
import '@simplewebauthn/server';
|
|
6
|
+
|
|
7
|
+
/** Configuration for the humankey Hono adapter. */
|
|
8
|
+
type HumanKeyHonoConfig = HumanKeyAdapterConfig;
|
|
9
|
+
/**
|
|
10
|
+
* Create a Hono app with humankey routes.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { Hono } from 'hono';
|
|
15
|
+
* import { createHumanKeyApp } from 'humankey/hono';
|
|
16
|
+
* const app = new Hono();
|
|
17
|
+
* app.route('/api', createHumanKeyApp({ ... }));
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
declare function createHumanKeyApp(config: HumanKeyHonoConfig): Hono;
|
|
21
|
+
|
|
22
|
+
export { type HumanKeyHonoConfig, createHumanKeyApp };
|
package/dist/hono.mjs
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MemoryChallengeStore,
|
|
3
|
+
handleChallenge,
|
|
4
|
+
handleRegister,
|
|
5
|
+
handleVerify,
|
|
6
|
+
resolveConfig
|
|
7
|
+
} from "./chunk-Y6KQC7WK.mjs";
|
|
8
|
+
import "./chunk-XXJAJHNP.mjs";
|
|
9
|
+
import "./chunk-CLQSCDXC.mjs";
|
|
10
|
+
|
|
11
|
+
// src/hono.ts
|
|
12
|
+
import { Hono } from "hono";
|
|
13
|
+
function createHumanKeyApp(config) {
|
|
14
|
+
const resolved = resolveConfig(config);
|
|
15
|
+
const app = new Hono();
|
|
16
|
+
app.post("/challenge", async (c) => {
|
|
17
|
+
const result = await handleChallenge(resolved);
|
|
18
|
+
return c.json(result.body, result.status);
|
|
19
|
+
});
|
|
20
|
+
app.post("/register", async (c) => {
|
|
21
|
+
const body = await c.req.json();
|
|
22
|
+
const result = await handleRegister(resolved, body);
|
|
23
|
+
return c.json(result.body, result.status);
|
|
24
|
+
});
|
|
25
|
+
app.post("/verify", async (c) => {
|
|
26
|
+
const body = await c.req.json();
|
|
27
|
+
const result = await handleVerify(resolved, body);
|
|
28
|
+
return c.json(result.body, result.status);
|
|
29
|
+
});
|
|
30
|
+
return app;
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
MemoryChallengeStore,
|
|
34
|
+
createHumanKeyApp
|
|
35
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -1,156 +1,17 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
+
var _chunkSZPXOH7Zcjs = require('./chunk-SZPXOH7Z.cjs');
|
|
3
4
|
|
|
4
5
|
|
|
6
|
+
var _chunkRQSBOE7Bcjs = require('./chunk-RQSBOE7B.cjs');
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
|
|
8
|
-
var
|
|
10
|
+
var _chunk2KMBF2THcjs = require('./chunk-2KMBF2TH.cjs');
|
|
9
11
|
|
|
10
|
-
// src/confirm.ts
|
|
11
|
-
async function createConfirmation(action) {
|
|
12
|
-
const hashBuffer = await _chunkJI6NIMGKcjs.hashAction.call(void 0, action);
|
|
13
|
-
const code = _chunkJI6NIMGKcjs.deriveConfirmationCode.call(void 0, hashBuffer);
|
|
14
|
-
const actionHash = _chunkJI6NIMGKcjs.bufferToBase64url.call(void 0, hashBuffer);
|
|
15
|
-
return { code, actionHash };
|
|
16
|
-
}
|
|
17
|
-
function validateConfirmation(confirmation, userInput) {
|
|
18
|
-
if (userInput.toUpperCase().trim() !== confirmation.code.toUpperCase()) {
|
|
19
|
-
throw new (0, _chunkJI6NIMGKcjs.HumanKeyError)(
|
|
20
|
-
"Confirmation code mismatch",
|
|
21
|
-
"CONFIRMATION_MISMATCH"
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
12
|
|
|
26
|
-
// src/tap.ts
|
|
27
|
-
var _browser = require('@simplewebauthn/browser');
|
|
28
|
-
async function requestTap(request) {
|
|
29
|
-
const {
|
|
30
|
-
challenge,
|
|
31
|
-
action,
|
|
32
|
-
confirmation,
|
|
33
|
-
userInput,
|
|
34
|
-
allowCredentials,
|
|
35
|
-
rpID,
|
|
36
|
-
userVerification = "required",
|
|
37
|
-
timeout = 6e4
|
|
38
|
-
} = request;
|
|
39
|
-
validateConfirmation(confirmation, userInput);
|
|
40
|
-
const actionHashBuffer = await _chunkJI6NIMGKcjs.hashAction.call(void 0, action);
|
|
41
|
-
const confirmationInput = `${confirmation.code}:${userInput.toUpperCase().trim()}`;
|
|
42
|
-
const confirmationHashBuffer = await crypto.subtle.digest(
|
|
43
|
-
"SHA-256",
|
|
44
|
-
new TextEncoder().encode(confirmationInput)
|
|
45
|
-
);
|
|
46
|
-
const challengeBuffer = _chunkJI6NIMGKcjs.base64urlToBuffer.call(void 0, challenge);
|
|
47
|
-
const finalChallenge = await _chunkJI6NIMGKcjs.combineAndHash.call(void 0,
|
|
48
|
-
challengeBuffer,
|
|
49
|
-
actionHashBuffer,
|
|
50
|
-
confirmationHashBuffer
|
|
51
|
-
);
|
|
52
|
-
const actionHash = _chunkJI6NIMGKcjs.bufferToBase64url.call(void 0, actionHashBuffer);
|
|
53
|
-
const confirmationHash = _chunkJI6NIMGKcjs.bufferToBase64url.call(void 0, confirmationHashBuffer);
|
|
54
|
-
try {
|
|
55
|
-
const response = await _browser.startAuthentication.call(void 0, {
|
|
56
|
-
optionsJSON: {
|
|
57
|
-
challenge: _chunkJI6NIMGKcjs.bufferToBase64url.call(void 0, finalChallenge),
|
|
58
|
-
rpId: rpID,
|
|
59
|
-
allowCredentials: allowCredentials.map((cred) => ({
|
|
60
|
-
id: cred.id,
|
|
61
|
-
type: "public-key",
|
|
62
|
-
transports: cred.transports
|
|
63
|
-
})),
|
|
64
|
-
userVerification,
|
|
65
|
-
timeout
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
return {
|
|
69
|
-
response,
|
|
70
|
-
action,
|
|
71
|
-
actionHash,
|
|
72
|
-
confirmationHash,
|
|
73
|
-
userInput: userInput.toUpperCase().trim()
|
|
74
|
-
};
|
|
75
|
-
} catch (error) {
|
|
76
|
-
if (error instanceof Error && error.name === "NotAllowedError") {
|
|
77
|
-
throw new (0, _chunkJI6NIMGKcjs.HumanKeyError)(
|
|
78
|
-
"User cancelled the hardware key tap",
|
|
79
|
-
"USER_CANCELLED",
|
|
80
|
-
error
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
throw error;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
13
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
async function registerKey(request) {
|
|
90
|
-
const {
|
|
91
|
-
challenge,
|
|
92
|
-
rpID,
|
|
93
|
-
rpName,
|
|
94
|
-
userName,
|
|
95
|
-
userDisplayName = userName,
|
|
96
|
-
excludeCredentials = [],
|
|
97
|
-
attestation = "direct",
|
|
98
|
-
userVerification = "required",
|
|
99
|
-
timeout = 6e4
|
|
100
|
-
} = request;
|
|
101
|
-
const userIdBytes = new TextEncoder().encode(userName);
|
|
102
|
-
const userIdHash = await crypto.subtle.digest("SHA-256", userIdBytes);
|
|
103
|
-
const userId = _chunkJI6NIMGKcjs.bufferToBase64url.call(void 0, userIdHash);
|
|
104
|
-
try {
|
|
105
|
-
const response = await _browser.startRegistration.call(void 0, {
|
|
106
|
-
optionsJSON: {
|
|
107
|
-
rp: { name: rpName, id: rpID },
|
|
108
|
-
user: {
|
|
109
|
-
id: userId,
|
|
110
|
-
name: userName,
|
|
111
|
-
displayName: userDisplayName
|
|
112
|
-
},
|
|
113
|
-
challenge,
|
|
114
|
-
pubKeyCredParams: [
|
|
115
|
-
{ alg: -7, type: "public-key" },
|
|
116
|
-
// ES256
|
|
117
|
-
{ alg: -257, type: "public-key" }
|
|
118
|
-
// RS256
|
|
119
|
-
],
|
|
120
|
-
timeout,
|
|
121
|
-
attestation,
|
|
122
|
-
excludeCredentials: excludeCredentials.map((cred) => ({
|
|
123
|
-
id: cred.id,
|
|
124
|
-
type: "public-key",
|
|
125
|
-
transports: cred.transports
|
|
126
|
-
})),
|
|
127
|
-
authenticatorSelection: {
|
|
128
|
-
authenticatorAttachment: "cross-platform",
|
|
129
|
-
residentKey: "preferred",
|
|
130
|
-
userVerification
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
return {
|
|
135
|
-
credentialId: response.id,
|
|
136
|
-
response,
|
|
137
|
-
transports: response.response.transports
|
|
138
|
-
};
|
|
139
|
-
} catch (error) {
|
|
140
|
-
if (error instanceof Error && error.name === "NotAllowedError") {
|
|
141
|
-
throw new (0, _chunkJI6NIMGKcjs.HumanKeyError)(
|
|
142
|
-
"User cancelled hardware key registration",
|
|
143
|
-
"USER_CANCELLED",
|
|
144
|
-
error
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
throw new (0, _chunkJI6NIMGKcjs.HumanKeyError)(
|
|
148
|
-
`Registration failed: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
149
|
-
"REGISTRATION_FAILED",
|
|
150
|
-
error
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
14
|
+
var _chunkJI6NIMGKcjs = require('./chunk-JI6NIMGK.cjs');
|
|
154
15
|
|
|
155
16
|
// src/support.ts
|
|
156
17
|
function isHumanKeySupported() {
|
|
@@ -164,4 +25,4 @@ function isHumanKeySupported() {
|
|
|
164
25
|
|
|
165
26
|
|
|
166
27
|
|
|
167
|
-
exports.HumanKeyError = _chunkJI6NIMGKcjs.HumanKeyError; exports.createConfirmation = createConfirmation; exports.hashAction = _chunkJI6NIMGKcjs.hashAction; exports.isHumanKeySupported = isHumanKeySupported; exports.registerKey = registerKey; exports.requestTap = requestTap; exports.validateConfirmation = validateConfirmation;
|
|
28
|
+
exports.HumanKeyError = _chunkJI6NIMGKcjs.HumanKeyError; exports.createConfirmation = _chunk2KMBF2THcjs.createConfirmation; exports.hashAction = _chunkJI6NIMGKcjs.hashAction; exports.isHumanKeySupported = isHumanKeySupported; exports.registerKey = _chunkRQSBOE7Bcjs.registerKey; exports.requestTap = _chunkSZPXOH7Zcjs.requestTap; exports.validateConfirmation = _chunk2KMBF2THcjs.validateConfirmation;
|
package/dist/index.mjs
CHANGED
|
@@ -1,157 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
requestTap
|
|
3
|
+
} from "./chunk-RANGHXC7.mjs";
|
|
4
|
+
import {
|
|
5
|
+
registerKey
|
|
6
|
+
} from "./chunk-U2AGXRNW.mjs";
|
|
7
|
+
import {
|
|
8
|
+
createConfirmation,
|
|
9
|
+
validateConfirmation
|
|
10
|
+
} from "./chunk-G2X46ZRM.mjs";
|
|
1
11
|
import {
|
|
2
12
|
HumanKeyError,
|
|
3
|
-
base64urlToBuffer,
|
|
4
|
-
bufferToBase64url,
|
|
5
|
-
combineAndHash,
|
|
6
|
-
deriveConfirmationCode,
|
|
7
13
|
hashAction
|
|
8
14
|
} from "./chunk-CLQSCDXC.mjs";
|
|
9
15
|
|
|
10
|
-
// src/confirm.ts
|
|
11
|
-
async function createConfirmation(action) {
|
|
12
|
-
const hashBuffer = await hashAction(action);
|
|
13
|
-
const code = deriveConfirmationCode(hashBuffer);
|
|
14
|
-
const actionHash = bufferToBase64url(hashBuffer);
|
|
15
|
-
return { code, actionHash };
|
|
16
|
-
}
|
|
17
|
-
function validateConfirmation(confirmation, userInput) {
|
|
18
|
-
if (userInput.toUpperCase().trim() !== confirmation.code.toUpperCase()) {
|
|
19
|
-
throw new HumanKeyError(
|
|
20
|
-
"Confirmation code mismatch",
|
|
21
|
-
"CONFIRMATION_MISMATCH"
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// src/tap.ts
|
|
27
|
-
import { startAuthentication } from "@simplewebauthn/browser";
|
|
28
|
-
async function requestTap(request) {
|
|
29
|
-
const {
|
|
30
|
-
challenge,
|
|
31
|
-
action,
|
|
32
|
-
confirmation,
|
|
33
|
-
userInput,
|
|
34
|
-
allowCredentials,
|
|
35
|
-
rpID,
|
|
36
|
-
userVerification = "required",
|
|
37
|
-
timeout = 6e4
|
|
38
|
-
} = request;
|
|
39
|
-
validateConfirmation(confirmation, userInput);
|
|
40
|
-
const actionHashBuffer = await hashAction(action);
|
|
41
|
-
const confirmationInput = `${confirmation.code}:${userInput.toUpperCase().trim()}`;
|
|
42
|
-
const confirmationHashBuffer = await crypto.subtle.digest(
|
|
43
|
-
"SHA-256",
|
|
44
|
-
new TextEncoder().encode(confirmationInput)
|
|
45
|
-
);
|
|
46
|
-
const challengeBuffer = base64urlToBuffer(challenge);
|
|
47
|
-
const finalChallenge = await combineAndHash(
|
|
48
|
-
challengeBuffer,
|
|
49
|
-
actionHashBuffer,
|
|
50
|
-
confirmationHashBuffer
|
|
51
|
-
);
|
|
52
|
-
const actionHash = bufferToBase64url(actionHashBuffer);
|
|
53
|
-
const confirmationHash = bufferToBase64url(confirmationHashBuffer);
|
|
54
|
-
try {
|
|
55
|
-
const response = await startAuthentication({
|
|
56
|
-
optionsJSON: {
|
|
57
|
-
challenge: bufferToBase64url(finalChallenge),
|
|
58
|
-
rpId: rpID,
|
|
59
|
-
allowCredentials: allowCredentials.map((cred) => ({
|
|
60
|
-
id: cred.id,
|
|
61
|
-
type: "public-key",
|
|
62
|
-
transports: cred.transports
|
|
63
|
-
})),
|
|
64
|
-
userVerification,
|
|
65
|
-
timeout
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
return {
|
|
69
|
-
response,
|
|
70
|
-
action,
|
|
71
|
-
actionHash,
|
|
72
|
-
confirmationHash,
|
|
73
|
-
userInput: userInput.toUpperCase().trim()
|
|
74
|
-
};
|
|
75
|
-
} catch (error) {
|
|
76
|
-
if (error instanceof Error && error.name === "NotAllowedError") {
|
|
77
|
-
throw new HumanKeyError(
|
|
78
|
-
"User cancelled the hardware key tap",
|
|
79
|
-
"USER_CANCELLED",
|
|
80
|
-
error
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
throw error;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// src/register.ts
|
|
88
|
-
import { startRegistration } from "@simplewebauthn/browser";
|
|
89
|
-
async function registerKey(request) {
|
|
90
|
-
const {
|
|
91
|
-
challenge,
|
|
92
|
-
rpID,
|
|
93
|
-
rpName,
|
|
94
|
-
userName,
|
|
95
|
-
userDisplayName = userName,
|
|
96
|
-
excludeCredentials = [],
|
|
97
|
-
attestation = "direct",
|
|
98
|
-
userVerification = "required",
|
|
99
|
-
timeout = 6e4
|
|
100
|
-
} = request;
|
|
101
|
-
const userIdBytes = new TextEncoder().encode(userName);
|
|
102
|
-
const userIdHash = await crypto.subtle.digest("SHA-256", userIdBytes);
|
|
103
|
-
const userId = bufferToBase64url(userIdHash);
|
|
104
|
-
try {
|
|
105
|
-
const response = await startRegistration({
|
|
106
|
-
optionsJSON: {
|
|
107
|
-
rp: { name: rpName, id: rpID },
|
|
108
|
-
user: {
|
|
109
|
-
id: userId,
|
|
110
|
-
name: userName,
|
|
111
|
-
displayName: userDisplayName
|
|
112
|
-
},
|
|
113
|
-
challenge,
|
|
114
|
-
pubKeyCredParams: [
|
|
115
|
-
{ alg: -7, type: "public-key" },
|
|
116
|
-
// ES256
|
|
117
|
-
{ alg: -257, type: "public-key" }
|
|
118
|
-
// RS256
|
|
119
|
-
],
|
|
120
|
-
timeout,
|
|
121
|
-
attestation,
|
|
122
|
-
excludeCredentials: excludeCredentials.map((cred) => ({
|
|
123
|
-
id: cred.id,
|
|
124
|
-
type: "public-key",
|
|
125
|
-
transports: cred.transports
|
|
126
|
-
})),
|
|
127
|
-
authenticatorSelection: {
|
|
128
|
-
authenticatorAttachment: "cross-platform",
|
|
129
|
-
residentKey: "preferred",
|
|
130
|
-
userVerification
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
return {
|
|
135
|
-
credentialId: response.id,
|
|
136
|
-
response,
|
|
137
|
-
transports: response.response.transports
|
|
138
|
-
};
|
|
139
|
-
} catch (error) {
|
|
140
|
-
if (error instanceof Error && error.name === "NotAllowedError") {
|
|
141
|
-
throw new HumanKeyError(
|
|
142
|
-
"User cancelled hardware key registration",
|
|
143
|
-
"USER_CANCELLED",
|
|
144
|
-
error
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
throw new HumanKeyError(
|
|
148
|
-
`Registration failed: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
149
|
-
"REGISTRATION_FAILED",
|
|
150
|
-
error
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
16
|
// src/support.ts
|
|
156
17
|
function isHumanKeySupported() {
|
|
157
18
|
return typeof window !== "undefined" && typeof window.PublicKeyCredential !== "undefined" && typeof navigator.credentials !== "undefined";
|
package/dist/nextjs.cjs
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
var _chunkG2IT2ZP5cjs = require('./chunk-G2IT2ZP5.cjs');
|
|
8
|
+
require('./chunk-FW3YUVJC.cjs');
|
|
9
|
+
require('./chunk-JI6NIMGK.cjs');
|
|
10
|
+
|
|
11
|
+
// src/nextjs.ts
|
|
12
|
+
function createHumanKeyHandlers(config) {
|
|
13
|
+
const resolved = _chunkG2IT2ZP5cjs.resolveConfig.call(void 0, config);
|
|
14
|
+
return {
|
|
15
|
+
/** POST handler for /challenge — generates and stores a challenge. */
|
|
16
|
+
challenge: async () => {
|
|
17
|
+
const result = await _chunkG2IT2ZP5cjs.handleChallenge.call(void 0, resolved);
|
|
18
|
+
return toResponse(result);
|
|
19
|
+
},
|
|
20
|
+
/** POST handler for /register — verifies registration and stores credential. */
|
|
21
|
+
register: async (req) => {
|
|
22
|
+
const body = await req.json();
|
|
23
|
+
const result = await _chunkG2IT2ZP5cjs.handleRegister.call(void 0, resolved, body);
|
|
24
|
+
return toResponse(result);
|
|
25
|
+
},
|
|
26
|
+
/** POST handler for /verify — verifies a tap proof. */
|
|
27
|
+
verify: async (req) => {
|
|
28
|
+
const body = await req.json();
|
|
29
|
+
const result = await _chunkG2IT2ZP5cjs.handleVerify.call(void 0, resolved, body);
|
|
30
|
+
return toResponse(result);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function toResponse(result) {
|
|
35
|
+
return Response.json(result.body, { status: result.status });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
exports.MemoryChallengeStore = _chunkG2IT2ZP5cjs.MemoryChallengeStore; exports.createHumanKeyHandlers = createHumanKeyHandlers;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { H as HumanKeyAdapterConfig } from './adapter-core-CoBcSqdG.cjs';
|
|
2
|
+
export { C as ChallengeStore, M as MemoryChallengeStore } from './adapter-core-CoBcSqdG.cjs';
|
|
3
|
+
export { A as ActionPayload, c as TapCredential, V as VerifyResult } from './types-By44RNIt.cjs';
|
|
4
|
+
import '@simplewebauthn/server';
|
|
5
|
+
|
|
6
|
+
/** Configuration for the humankey Next.js adapter. */
|
|
7
|
+
type HumanKeyNextConfig = HumanKeyAdapterConfig;
|
|
8
|
+
/**
|
|
9
|
+
* Create Next.js App Router route handlers for humankey.
|
|
10
|
+
*
|
|
11
|
+
* Usage (one file per route):
|
|
12
|
+
* ```ts
|
|
13
|
+
* // app/api/humankey/challenge/route.ts
|
|
14
|
+
* import { createHumanKeyHandlers } from 'humankey/nextjs';
|
|
15
|
+
* const hk = createHumanKeyHandlers({ ... });
|
|
16
|
+
* export const POST = hk.challenge;
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
declare function createHumanKeyHandlers(config: HumanKeyNextConfig): {
|
|
20
|
+
/** POST handler for /challenge — generates and stores a challenge. */
|
|
21
|
+
challenge: () => Promise<Response>;
|
|
22
|
+
/** POST handler for /register — verifies registration and stores credential. */
|
|
23
|
+
register: (req: Request) => Promise<Response>;
|
|
24
|
+
/** POST handler for /verify — verifies a tap proof. */
|
|
25
|
+
verify: (req: Request) => Promise<Response>;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export { type HumanKeyNextConfig, createHumanKeyHandlers };
|
package/dist/nextjs.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { H as HumanKeyAdapterConfig } from './adapter-core-CFN3y3L0.js';
|
|
2
|
+
export { C as ChallengeStore, M as MemoryChallengeStore } from './adapter-core-CFN3y3L0.js';
|
|
3
|
+
export { A as ActionPayload, c as TapCredential, V as VerifyResult } from './types-By44RNIt.js';
|
|
4
|
+
import '@simplewebauthn/server';
|
|
5
|
+
|
|
6
|
+
/** Configuration for the humankey Next.js adapter. */
|
|
7
|
+
type HumanKeyNextConfig = HumanKeyAdapterConfig;
|
|
8
|
+
/**
|
|
9
|
+
* Create Next.js App Router route handlers for humankey.
|
|
10
|
+
*
|
|
11
|
+
* Usage (one file per route):
|
|
12
|
+
* ```ts
|
|
13
|
+
* // app/api/humankey/challenge/route.ts
|
|
14
|
+
* import { createHumanKeyHandlers } from 'humankey/nextjs';
|
|
15
|
+
* const hk = createHumanKeyHandlers({ ... });
|
|
16
|
+
* export const POST = hk.challenge;
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
declare function createHumanKeyHandlers(config: HumanKeyNextConfig): {
|
|
20
|
+
/** POST handler for /challenge — generates and stores a challenge. */
|
|
21
|
+
challenge: () => Promise<Response>;
|
|
22
|
+
/** POST handler for /register — verifies registration and stores credential. */
|
|
23
|
+
register: (req: Request) => Promise<Response>;
|
|
24
|
+
/** POST handler for /verify — verifies a tap proof. */
|
|
25
|
+
verify: (req: Request) => Promise<Response>;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export { type HumanKeyNextConfig, createHumanKeyHandlers };
|