@revibase/ctap2-js 0.1.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.
Files changed (69) hide show
  1. package/README.md +65 -0
  2. package/lib/apdu.d.ts +56 -0
  3. package/lib/apdu.d.ts.map +1 -0
  4. package/lib/apdu.js +225 -0
  5. package/lib/buildRequests.d.ts +11 -0
  6. package/lib/buildRequests.d.ts.map +1 -0
  7. package/lib/buildRequests.js +24 -0
  8. package/lib/constants.d.ts +11 -0
  9. package/lib/constants.d.ts.map +1 -0
  10. package/lib/constants.js +15 -0
  11. package/lib/ctap2/cborUtils.d.ts +14 -0
  12. package/lib/ctap2/cborUtils.d.ts.map +1 -0
  13. package/lib/ctap2/cborUtils.js +141 -0
  14. package/lib/ctap2/getAssertion.d.ts +32 -0
  15. package/lib/ctap2/getAssertion.d.ts.map +1 -0
  16. package/lib/ctap2/getAssertion.js +104 -0
  17. package/lib/ctap2/makeCredential.d.ts +37 -0
  18. package/lib/ctap2/makeCredential.d.ts.map +1 -0
  19. package/lib/ctap2/makeCredential.js +118 -0
  20. package/lib/errors.d.ts +7 -0
  21. package/lib/errors.d.ts.map +1 -0
  22. package/lib/errors.js +13 -0
  23. package/lib/helpers/authDataExtensions.d.ts +9 -0
  24. package/lib/helpers/authDataExtensions.d.ts.map +1 -0
  25. package/lib/helpers/authDataExtensions.js +192 -0
  26. package/lib/helpers/base64url.d.ts +3 -0
  27. package/lib/helpers/base64url.d.ts.map +1 -0
  28. package/lib/helpers/base64url.js +29 -0
  29. package/lib/helpers/clientData.d.ts +9 -0
  30. package/lib/helpers/clientData.d.ts.map +1 -0
  31. package/lib/helpers/clientData.js +18 -0
  32. package/lib/helpers/fromWebAuthnJson.d.ts +6 -0
  33. package/lib/helpers/fromWebAuthnJson.d.ts.map +1 -0
  34. package/lib/helpers/fromWebAuthnJson.js +125 -0
  35. package/lib/helpers/webauthnResponses.d.ts +21 -0
  36. package/lib/helpers/webauthnResponses.d.ts.map +1 -0
  37. package/lib/helpers/webauthnResponses.js +51 -0
  38. package/lib/helpers/webauthnTypes.d.ts +6 -0
  39. package/lib/helpers/webauthnTypes.d.ts.map +1 -0
  40. package/lib/helpers/webauthnTypes.js +2 -0
  41. package/lib/index.d.ts +4 -0
  42. package/lib/index.d.ts.map +1 -0
  43. package/lib/index.js +8 -0
  44. package/lib/parseResponses.d.ts +19 -0
  45. package/lib/parseResponses.d.ts.map +1 -0
  46. package/lib/parseResponses.js +37 -0
  47. package/lib/publicApi.d.ts +15 -0
  48. package/lib/publicApi.d.ts.map +1 -0
  49. package/lib/publicApi.js +83 -0
  50. package/lib/types.d.ts +10 -0
  51. package/lib/types.d.ts.map +1 -0
  52. package/lib/types.js +2 -0
  53. package/package.json +35 -0
  54. package/src/apdu.ts +285 -0
  55. package/src/constants.ts +16 -0
  56. package/src/ctap2/cborUtils.ts +155 -0
  57. package/src/ctap2/getAssertion.ts +154 -0
  58. package/src/ctap2/makeCredential.ts +173 -0
  59. package/src/errors.ts +11 -0
  60. package/src/helpers/authDataExtensions.ts +214 -0
  61. package/src/helpers/base64url.ts +24 -0
  62. package/src/helpers/clientData.ts +24 -0
  63. package/src/helpers/fromWebAuthnJson.ts +175 -0
  64. package/src/helpers/webauthnResponses.ts +113 -0
  65. package/src/index.ts +6 -0
  66. package/src/parseResponses.ts +67 -0
  67. package/src/publicApi.ts +152 -0
  68. package/src/types.ts +16 -0
  69. package/tsconfig.json +16 -0
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseAuthenticatorGetAssertionResponse = exports.encodeAuthenticatorGetAssertionRequest = void 0;
4
+ const cbor_x_1 = require("cbor-x");
5
+ const apdu_1 = require("../apdu");
6
+ const constants_1 = require("../constants");
7
+ const errors_1 = require("../errors");
8
+ const cborUtils_1 = require("./cborUtils");
9
+ function buildRequestMap(req) {
10
+ const m = new Map();
11
+ m.set(1, req.rpId);
12
+ m.set(2, req.clientDataHash);
13
+ if (req.allowCredentials?.length) {
14
+ m.set(3, req.allowCredentials.map((c) => ({
15
+ id: c.id,
16
+ type: c.type ?? "public-key",
17
+ })));
18
+ }
19
+ if (req.extensions && Object.keys(req.extensions).length > 0) {
20
+ m.set(4, req.extensions);
21
+ }
22
+ if (req.options &&
23
+ (req.options.up !== undefined || req.options.uv !== undefined)) {
24
+ const opt = {};
25
+ if (req.options.up !== undefined) {
26
+ opt.up = req.options.up;
27
+ }
28
+ if (req.options.uv !== undefined) {
29
+ opt.uv = req.options.uv;
30
+ }
31
+ m.set(5, opt);
32
+ }
33
+ return m;
34
+ }
35
+ function decodeAssertionMap(decoded) {
36
+ const authData = (0, cborUtils_1.bytesView)((0, cborUtils_1.cborMapGet)(decoded, 2));
37
+ const signature = (0, cborUtils_1.bytesView)((0, cborUtils_1.cborMapGet)(decoded, 3));
38
+ if (!authData || !signature) {
39
+ throw new errors_1.ApduError("missing authData (2) or signature (3) in response");
40
+ }
41
+ const out = {
42
+ authData,
43
+ signature,
44
+ };
45
+ const credRaw = (0, cborUtils_1.cborMapGet)(decoded, 1);
46
+ if (credRaw !== null && typeof credRaw === "object") {
47
+ const o = credRaw;
48
+ const id = (0, cborUtils_1.bytesView)(o.id);
49
+ if (id) {
50
+ out.credential = {
51
+ id,
52
+ type: typeof o.type === "string" ? o.type : undefined,
53
+ };
54
+ }
55
+ }
56
+ const userRaw = (0, cborUtils_1.cborMapGet)(decoded, 4);
57
+ if (userRaw !== null && typeof userRaw === "object") {
58
+ const o = userRaw;
59
+ const id = (0, cborUtils_1.bytesView)(o.id);
60
+ if (id) {
61
+ out.user = {
62
+ id,
63
+ name: typeof o.name === "string" ? o.name : undefined,
64
+ displayName: typeof o.displayName === "string"
65
+ ? o.displayName
66
+ : undefined,
67
+ icon: typeof o.icon === "string" ? o.icon : undefined,
68
+ };
69
+ }
70
+ }
71
+ const nRaw = (0, cborUtils_1.cborMapGet)(decoded, 5);
72
+ let n;
73
+ if (typeof nRaw === "number" && Number.isFinite(nRaw)) {
74
+ n = Math.trunc(nRaw);
75
+ }
76
+ else if (typeof nRaw === "bigint") {
77
+ n = Number(nRaw);
78
+ }
79
+ if (n !== undefined) {
80
+ out.numberOfCredentials = n;
81
+ }
82
+ const lbk = (0, cborUtils_1.bytesView)((0, cborUtils_1.cborMapGet)(decoded, 7));
83
+ if (lbk) {
84
+ out.largeBlobKey = lbk;
85
+ }
86
+ return out;
87
+ }
88
+ function encodeAuthenticatorGetAssertionRequest(req) {
89
+ if (req.clientDataHash.length !== 32) {
90
+ throw new errors_1.ApduError("clientDataHash must be 32 bytes (SHA-256)");
91
+ }
92
+ const enc = (0, cborUtils_1.encodeCtapCbor)(buildRequestMap(req));
93
+ const frame = new Uint8Array(1 + enc.length);
94
+ frame[0] = constants_1.CTAP_CBOR_ASSERT;
95
+ frame.set(enc, 1);
96
+ return frame;
97
+ }
98
+ exports.encodeAuthenticatorGetAssertionRequest = encodeAuthenticatorGetAssertionRequest;
99
+ function parseAuthenticatorGetAssertionResponse(apduResponseIncludingSw) {
100
+ const cborMapBytes = (0, apdu_1.unwrapCtaphidCborBody)((0, apdu_1.parseCtaphidCborFromApduResponse)(apduResponseIncludingSw));
101
+ const decoded = (0, cbor_x_1.decode)(cborMapBytes);
102
+ return decodeAssertionMap(decoded);
103
+ }
104
+ exports.parseAuthenticatorGetAssertionResponse = parseAuthenticatorGetAssertionResponse;
@@ -0,0 +1,37 @@
1
+ export interface AuthenticatorMakeCredentialRequest {
2
+ clientDataHash: Uint8Array;
3
+ rp: {
4
+ id: string;
5
+ name: string;
6
+ };
7
+ user: {
8
+ id: Uint8Array;
9
+ name: string;
10
+ displayName: string;
11
+ icon?: string;
12
+ };
13
+ pubKeyCredParams: Array<{
14
+ alg: number;
15
+ type: string;
16
+ }>;
17
+ excludeCredentials?: Array<{
18
+ id: Uint8Array;
19
+ type?: string;
20
+ }>;
21
+ extensions?: Record<string, unknown>;
22
+ options?: {
23
+ rk?: boolean;
24
+ uv?: boolean;
25
+ };
26
+ }
27
+ export interface AuthenticatorMakeCredentialResponse {
28
+ fmt: string;
29
+ authData: Uint8Array;
30
+ attStmt: Record<string, unknown>;
31
+ largeBlobKey?: Uint8Array;
32
+ }
33
+ export declare function encodeAuthenticatorMakeCredentialRequest(req: AuthenticatorMakeCredentialRequest): Uint8Array;
34
+ export declare function parseAuthenticatorMakeCredentialResponse(apduResponseIncludingSw: Uint8Array): AuthenticatorMakeCredentialResponse;
35
+ export declare function buildAttestationObjectBytes(fmt: string, authData: Uint8Array, attStmt: Record<string, unknown>): Uint8Array;
36
+ export declare function extractCredentialIdFromAuthData(authData: Uint8Array): Uint8Array;
37
+ //# sourceMappingURL=makeCredential.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"makeCredential.d.ts","sourceRoot":"","sources":["../../src/ctap2/makeCredential.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,kCAAkC;IAClD,cAAc,EAAE,UAAU,CAAC;IAC3B,EAAE,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC,IAAI,EAAE;QACL,EAAE,EAAE,UAAU,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,gBAAgB,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvD,kBAAkB,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,UAAU,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,OAAO,CAAC;QAAC,EAAE,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACzC;AAED,MAAM,WAAW,mCAAmC;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,UAAU,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,UAAU,CAAC;CAC1B;AAoDD,wBAAgB,wCAAwC,CACvD,GAAG,EAAE,kCAAkC,GACrC,UAAU,CAcZ;AAED,wBAAgB,wCAAwC,CACvD,uBAAuB,EAAE,UAAU,GACjC,mCAAmC,CAgCrC;AAED,wBAAgB,2BAA2B,CAC1C,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,UAAU,EACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,UAAU,CAOZ;AAED,wBAAgB,+BAA+B,CAC9C,QAAQ,EAAE,UAAU,GAClB,UAAU,CAsBZ"}
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractCredentialIdFromAuthData = exports.buildAttestationObjectBytes = exports.parseAuthenticatorMakeCredentialResponse = exports.encodeAuthenticatorMakeCredentialRequest = void 0;
4
+ const cbor_x_1 = require("cbor-x");
5
+ const apdu_1 = require("../apdu");
6
+ const constants_1 = require("../constants");
7
+ const errors_1 = require("../errors");
8
+ const cborUtils_1 = require("./cborUtils");
9
+ function buildMakeCredentialMap(req) {
10
+ const m = new Map();
11
+ m.set(1, req.clientDataHash);
12
+ m.set(2, { id: req.rp.id, name: req.rp.name });
13
+ const u = {
14
+ id: req.user.id,
15
+ name: req.user.name,
16
+ displayName: req.user.displayName,
17
+ };
18
+ if (req.user.icon !== undefined) {
19
+ u.icon = req.user.icon;
20
+ }
21
+ m.set(3, u);
22
+ m.set(4, req.pubKeyCredParams.map((p) => ({
23
+ alg: p.alg,
24
+ type: p.type ?? "public-key",
25
+ })));
26
+ if (req.excludeCredentials?.length) {
27
+ m.set(5, req.excludeCredentials.map((c) => ({
28
+ id: c.id,
29
+ type: c.type ?? "public-key",
30
+ })));
31
+ }
32
+ if (req.extensions && Object.keys(req.extensions).length > 0) {
33
+ m.set(6, req.extensions);
34
+ }
35
+ if (req.options &&
36
+ (req.options.rk !== undefined || req.options.uv !== undefined)) {
37
+ const opt = {};
38
+ if (req.options.rk !== undefined) {
39
+ opt.rk = req.options.rk;
40
+ }
41
+ if (req.options.uv !== undefined) {
42
+ opt.uv = req.options.uv;
43
+ }
44
+ m.set(7, opt);
45
+ }
46
+ return m;
47
+ }
48
+ function encodeAuthenticatorMakeCredentialRequest(req) {
49
+ if (req.clientDataHash.length !== 32) {
50
+ throw new errors_1.ApduError("clientDataHash must be 32 bytes (SHA-256)");
51
+ }
52
+ if (!req.pubKeyCredParams.length) {
53
+ throw new errors_1.ApduError("pubKeyCredParams must not be empty");
54
+ }
55
+ const enc = (0, cborUtils_1.encodeCtapCbor)(buildMakeCredentialMap(req));
56
+ const frame = new Uint8Array(1 + enc.length);
57
+ frame[0] = constants_1.CTAP_CBOR_MAKE_CRED;
58
+ frame.set(enc, 1);
59
+ return frame;
60
+ }
61
+ exports.encodeAuthenticatorMakeCredentialRequest = encodeAuthenticatorMakeCredentialRequest;
62
+ function parseAuthenticatorMakeCredentialResponse(apduResponseIncludingSw) {
63
+ const cborMapBytes = (0, apdu_1.unwrapCtaphidCborBody)((0, apdu_1.parseCtaphidCborFromApduResponse)(apduResponseIncludingSw));
64
+ const decoded = (0, cbor_x_1.decode)(cborMapBytes);
65
+ const fmtRaw = (0, cborUtils_1.cborMapGet)(decoded, 1);
66
+ const fmt = typeof fmtRaw === "string" ? fmtRaw : undefined;
67
+ const authData = (0, cborUtils_1.bytesView)((0, cborUtils_1.cborMapGet)(decoded, 2));
68
+ const attStmtRaw = (0, cborUtils_1.cborMapGet)(decoded, 3);
69
+ if (attStmtRaw === null ||
70
+ typeof attStmtRaw !== "object" ||
71
+ Array.isArray(attStmtRaw)) {
72
+ throw new errors_1.ApduError("attStmt (key 3) must be a CBOR map");
73
+ }
74
+ const attStmt = attStmtRaw;
75
+ if (!fmt || !authData) {
76
+ throw new errors_1.ApduError("missing fmt (1) or authData (2) in makeCredential response");
77
+ }
78
+ const out = {
79
+ fmt,
80
+ authData,
81
+ attStmt,
82
+ };
83
+ const lbk = (0, cborUtils_1.bytesView)((0, cborUtils_1.cborMapGet)(decoded, 5));
84
+ if (lbk) {
85
+ out.largeBlobKey = lbk;
86
+ }
87
+ return out;
88
+ }
89
+ exports.parseAuthenticatorMakeCredentialResponse = parseAuthenticatorMakeCredentialResponse;
90
+ function buildAttestationObjectBytes(fmt, authData, attStmt) {
91
+ // WebAuthn attestation object is CBOR; use CTAP2 canonical rules (CTAP §8) for interoperability.
92
+ return (0, cborUtils_1.encodeCtapCbor)({
93
+ fmt,
94
+ authData,
95
+ attStmt,
96
+ });
97
+ }
98
+ exports.buildAttestationObjectBytes = buildAttestationObjectBytes;
99
+ function extractCredentialIdFromAuthData(authData) {
100
+ if (authData.length < 37) {
101
+ throw new errors_1.ApduError("authData too short");
102
+ }
103
+ const flags = authData[32];
104
+ if ((flags & 0x40) === 0) {
105
+ throw new errors_1.ApduError("authData missing AT flag (attested credential data)");
106
+ }
107
+ let off = 37 + 16;
108
+ if (off + 2 > authData.length) {
109
+ throw new errors_1.ApduError("authData truncated before credential id length");
110
+ }
111
+ const credIdLen = (authData[off] << 8) | authData[off + 1];
112
+ off += 2;
113
+ if (off + credIdLen > authData.length) {
114
+ throw new errors_1.ApduError("credential id length out of range");
115
+ }
116
+ return authData.slice(off, off + credIdLen);
117
+ }
118
+ exports.extractCredentialIdFromAuthData = extractCredentialIdFromAuthData;
@@ -0,0 +1,7 @@
1
+ export declare class ApduError extends Error {
2
+ readonly cause?: unknown;
3
+ constructor(message: string, options?: {
4
+ cause?: unknown;
5
+ });
6
+ }
7
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAU,SAAQ,KAAK;IAClC,SAAiB,KAAK,CAAC,EAAE,OAAO,CAAC;gBAErB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAO3D"}
package/lib/errors.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApduError = void 0;
4
+ class ApduError extends Error {
5
+ constructor(message, options) {
6
+ super(message);
7
+ this.name = "ApduError";
8
+ if (options?.cause !== undefined) {
9
+ this.cause = options.cause;
10
+ }
11
+ }
12
+ }
13
+ exports.ApduError = ApduError;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Parse the **extensions** CBOR map from WebAuthn authenticator data (ED flag).
3
+ * This is what browsers merge into `getClientExtensionResults()` for authenticator
4
+ * extension outputs; pure **client** extensions are not present here.
5
+ *
6
+ * @returns Plain object suitable for `clientExtensionResults`, or `{}` if ED is clear.
7
+ */
8
+ export declare function parseAuthenticatorDataExtensions(authData: Uint8Array): Record<string, unknown>;
9
+ //# sourceMappingURL=authDataExtensions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authDataExtensions.d.ts","sourceRoot":"","sources":["../../src/helpers/authDataExtensions.ts"],"names":[],"mappings":"AA0LA;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC/C,QAAQ,EAAE,UAAU,GAClB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkBzB"}
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseAuthenticatorDataExtensions = void 0;
4
+ const cbor_x_1 = require("cbor-x");
5
+ /** WebAuthn authenticator data flags (byte index 32). */
6
+ const FLAG_AT = 0x40;
7
+ const FLAG_ED = 0x80;
8
+ /**
9
+ * Skip one definite CBOR data item (RFC 8949). Used to skip the COSE public key
10
+ * in attested credential data. Indefinite-length items throw (not used in WebAuthn authData).
11
+ */
12
+ function skipOneCborItem(buf, i) {
13
+ const first = buf[i];
14
+ const mt = first >> 5;
15
+ const ai = first & 0x1f;
16
+ let p = i + 1;
17
+ if (mt === 0 || mt === 1) {
18
+ if (ai < 24) {
19
+ return p;
20
+ }
21
+ if (ai === 24) {
22
+ return p + 1;
23
+ }
24
+ if (ai === 25) {
25
+ return p + 2;
26
+ }
27
+ if (ai === 26) {
28
+ return p + 4;
29
+ }
30
+ if (ai === 27) {
31
+ return p + 8;
32
+ }
33
+ throw new Error("CBOR: invalid integer encoding");
34
+ }
35
+ if (mt === 2 || mt === 3) {
36
+ const { len, next } = readLength(ai, buf, p);
37
+ return next + len;
38
+ }
39
+ if (mt === 4) {
40
+ if (ai === 31) {
41
+ throw new Error("CBOR: indefinite array not supported in authData");
42
+ }
43
+ const { len, next } = readLength(ai, buf, p);
44
+ let q = next;
45
+ for (let k = 0; k < len; k++) {
46
+ q = skipOneCborItem(buf, q);
47
+ }
48
+ return q;
49
+ }
50
+ if (mt === 5) {
51
+ if (ai === 31) {
52
+ throw new Error("CBOR: indefinite map not supported in authData");
53
+ }
54
+ const { len, next } = readLength(ai, buf, p);
55
+ let q = next;
56
+ for (let k = 0; k < len; k++) {
57
+ q = skipOneCborItem(buf, q);
58
+ q = skipOneCborItem(buf, q);
59
+ }
60
+ return q;
61
+ }
62
+ if (mt === 6) {
63
+ const { next } = readTagNumber(ai, buf, p);
64
+ return skipOneCborItem(buf, next);
65
+ }
66
+ if (mt === 7) {
67
+ if (ai < 24) {
68
+ return p;
69
+ }
70
+ if (ai === 24) {
71
+ return p + 1;
72
+ }
73
+ if (ai === 25) {
74
+ return p + 2;
75
+ }
76
+ if (ai === 26) {
77
+ return p + 5;
78
+ }
79
+ if (ai === 27) {
80
+ return p + 9;
81
+ }
82
+ throw new Error("CBOR: invalid simple/float encoding");
83
+ }
84
+ throw new Error("CBOR: unknown major type");
85
+ }
86
+ function readLength(ai, buf, p) {
87
+ if (ai < 24) {
88
+ return { len: ai, next: p };
89
+ }
90
+ if (ai === 24) {
91
+ return { len: buf[p], next: p + 1 };
92
+ }
93
+ if (ai === 25) {
94
+ return { len: (buf[p] << 8) | buf[p + 1], next: p + 2 };
95
+ }
96
+ if (ai === 26) {
97
+ const len = ((buf[p] << 24) |
98
+ (buf[p + 1] << 16) |
99
+ (buf[p + 2] << 8) |
100
+ buf[p + 3]) >>>
101
+ 0;
102
+ return { len, next: p + 4 };
103
+ }
104
+ if (ai === 27) {
105
+ const hi = (buf[p] << 24) | (buf[p + 1] << 16) | (buf[p + 2] << 8) | buf[p + 3];
106
+ const lo = (buf[p + 4] << 24) |
107
+ (buf[p + 5] << 16) |
108
+ (buf[p + 6] << 8) |
109
+ buf[p + 7];
110
+ const n = (BigInt(hi >>> 0) << 32n) | BigInt(lo >>> 0);
111
+ if (n > BigInt(Number.MAX_SAFE_INTEGER)) {
112
+ throw new Error("CBOR: length too large");
113
+ }
114
+ return { len: Number(n), next: p + 8 };
115
+ }
116
+ throw new Error("CBOR: invalid length encoding");
117
+ }
118
+ function readTagNumber(ai, buf, p) {
119
+ if (ai < 24) {
120
+ return { next: p };
121
+ }
122
+ if (ai === 24) {
123
+ return { next: p + 1 };
124
+ }
125
+ if (ai === 25) {
126
+ return { next: p + 2 };
127
+ }
128
+ if (ai === 26) {
129
+ return { next: p + 4 };
130
+ }
131
+ if (ai === 27) {
132
+ return { next: p + 8 };
133
+ }
134
+ throw new Error("CBOR: invalid tag encoding");
135
+ }
136
+ /**
137
+ * Advance past attested credential data (starts at `start`, first byte of AAGUID).
138
+ */
139
+ function skipAttestedCredentialData(authData, start) {
140
+ if (authData.length < start + 18) {
141
+ throw new Error("authData: truncated attested credential data header");
142
+ }
143
+ let off = start + 16;
144
+ const credIdLen = (authData[off] << 8) | authData[off + 1];
145
+ off += 2 + credIdLen;
146
+ if (off > authData.length) {
147
+ throw new Error("authData: credential id out of range");
148
+ }
149
+ return skipOneCborItem(authData, off);
150
+ }
151
+ function cborExtensionsToRecord(decoded) {
152
+ if (decoded instanceof Map) {
153
+ const o = {};
154
+ for (const [k, v] of decoded) {
155
+ if (typeof k === "string") {
156
+ o[k] = v;
157
+ }
158
+ }
159
+ return o;
160
+ }
161
+ if (decoded !== null && typeof decoded === "object" && !Array.isArray(decoded)) {
162
+ return { ...decoded };
163
+ }
164
+ return {};
165
+ }
166
+ /**
167
+ * Parse the **extensions** CBOR map from WebAuthn authenticator data (ED flag).
168
+ * This is what browsers merge into `getClientExtensionResults()` for authenticator
169
+ * extension outputs; pure **client** extensions are not present here.
170
+ *
171
+ * @returns Plain object suitable for `clientExtensionResults`, or `{}` if ED is clear.
172
+ */
173
+ function parseAuthenticatorDataExtensions(authData) {
174
+ if (authData.length < 37) {
175
+ return {};
176
+ }
177
+ const flags = authData[32];
178
+ let offset = 37;
179
+ if (flags & FLAG_AT) {
180
+ offset = skipAttestedCredentialData(authData, offset);
181
+ }
182
+ if ((flags & FLAG_ED) === 0) {
183
+ return {};
184
+ }
185
+ if (offset >= authData.length) {
186
+ return {};
187
+ }
188
+ const extBytes = authData.subarray(offset);
189
+ const decoded = (0, cbor_x_1.decode)(extBytes);
190
+ return cborExtensionsToRecord(decoded);
191
+ }
192
+ exports.parseAuthenticatorDataExtensions = parseAuthenticatorDataExtensions;
@@ -0,0 +1,3 @@
1
+ export declare function base64URLStringToBuffer(base64URLString: string): ArrayBuffer;
2
+ export declare function bufferToBase64URLString(buffer: Uint8Array): string;
3
+ //# sourceMappingURL=base64url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base64url.d.ts","sourceRoot":"","sources":["../../src/helpers/base64url.ts"],"names":[],"mappings":"AAAA,wBAAgB,uBAAuB,CAAC,eAAe,EAAE,MAAM,eAW9D;AACD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,UAAU,UAWzD"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.bufferToBase64URLString = exports.base64URLStringToBuffer = void 0;
4
+ function base64URLStringToBuffer(base64URLString) {
5
+ const base64 = base64URLString.replace(/-/g, "+").replace(/_/g, "/");
6
+ const padLength = (4 - (base64.length % 4)) % 4;
7
+ const padded = base64.padEnd(base64.length + padLength, "=");
8
+ const binary = atob(padded);
9
+ const buffer = new ArrayBuffer(binary.length);
10
+ const bytes = new Uint8Array(buffer);
11
+ for (let i = 0; i < binary.length; i++) {
12
+ bytes[i] = binary.charCodeAt(i);
13
+ }
14
+ return buffer;
15
+ }
16
+ exports.base64URLStringToBuffer = base64URLStringToBuffer;
17
+ function bufferToBase64URLString(buffer) {
18
+ const bytes = new Uint8Array(buffer);
19
+ let str = "";
20
+ for (const charCode of bytes) {
21
+ str += String.fromCharCode(charCode);
22
+ }
23
+ const base64String = btoa(str);
24
+ return base64String
25
+ .replace(/\+/g, "-")
26
+ .replace(/\//g, "_")
27
+ .replace(/=/g, "");
28
+ }
29
+ exports.bufferToBase64URLString = bufferToBase64URLString;
@@ -0,0 +1,9 @@
1
+ interface CollectedClientDataInput {
2
+ challenge: string;
3
+ origin: string;
4
+ crossOrigin: boolean;
5
+ topOrigin?: string;
6
+ }
7
+ export declare function buildCollectedClientDataJSON(type: "webauthn.get" | "webauthn.create", input: CollectedClientDataInput): string;
8
+ export {};
9
+ //# sourceMappingURL=clientData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clientData.d.ts","sourceRoot":"","sources":["../../src/helpers/clientData.ts"],"names":[],"mappings":"AAAA,UAAU,wBAAwB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,cAAc,GAAG,iBAAiB,EACxC,KAAK,EAAE,wBAAwB,GAC9B,MAAM,CAaR"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildCollectedClientDataJSON = void 0;
4
+ function buildCollectedClientDataJSON(type, input) {
5
+ const o = {
6
+ type,
7
+ challenge: input.challenge,
8
+ origin: input.origin,
9
+ };
10
+ if (input.crossOrigin !== undefined) {
11
+ o.crossOrigin = input.crossOrigin;
12
+ }
13
+ if (input.topOrigin !== undefined) {
14
+ o.topOrigin = input.topOrigin;
15
+ }
16
+ return JSON.stringify(o);
17
+ }
18
+ exports.buildCollectedClientDataJSON = buildCollectedClientDataJSON;
@@ -0,0 +1,6 @@
1
+ import { type AuthenticatorGetAssertionRequest } from "../ctap2/getAssertion";
2
+ import { type AuthenticatorMakeCredentialRequest } from "../ctap2/makeCredential";
3
+ import { PublicKeyCredentialCreationOptionsJSONWithNfc, PublicKeyCredentialRequestOptionsJSONWithNfc } from "../types";
4
+ export declare function authenticatorGetAssertionRequestFromPublicKeyCredentialRequestOptionsJSON(args: PublicKeyCredentialRequestOptionsJSONWithNfc): AuthenticatorGetAssertionRequest;
5
+ export declare function authenticatorMakeCredentialRequestFromPublicKeyCredentialCreationOptionsJSON(args: PublicKeyCredentialCreationOptionsJSONWithNfc): AuthenticatorMakeCredentialRequest;
6
+ //# sourceMappingURL=fromWebAuthnJson.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fromWebAuthnJson.d.ts","sourceRoot":"","sources":["../../src/helpers/fromWebAuthnJson.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,gCAAgC,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,KAAK,kCAAkC,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EACL,6CAA6C,EAC7C,4CAA4C,EAC7C,MAAM,UAAU,CAAC;AAgElB,wBAAgB,yEAAyE,CACvF,IAAI,EAAE,4CAA4C,GACjD,gCAAgC,CA0ClC;AAED,wBAAgB,4EAA4E,CAC1F,IAAI,EAAE,6CAA6C,GAClD,kCAAkC,CAqDpC"}