accounts 0.4.20 → 0.4.21
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/CHANGELOG.md +7 -0
- package/README.md +1 -1
- package/dist/core/{Ceremony.d.ts → WebAuthnCeremony.d.ts} +11 -11
- package/dist/core/WebAuthnCeremony.d.ts.map +1 -0
- package/dist/core/{Ceremony.js → WebAuthnCeremony.js} +7 -7
- package/dist/core/WebAuthnCeremony.js.map +1 -0
- package/dist/core/adapters/webAuthn.d.ts +5 -5
- package/dist/core/adapters/webAuthn.d.ts.map +1 -1
- package/dist/core/adapters/webAuthn.js +3 -3
- package/dist/core/adapters/webAuthn.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/server/Handler.d.ts +3 -3
- package/dist/server/Handler.js +2 -2
- package/package.json +1 -1
- package/src/core/Provider.browser.test.ts +2 -2
- package/src/core/{Ceremony.browser.test.ts → WebAuthnCeremony.browser.test.ts} +6 -6
- package/src/core/{Ceremony.test.ts → WebAuthnCeremony.test.ts} +10 -10
- package/src/core/{Ceremony.ts → WebAuthnCeremony.ts} +10 -10
- package/src/core/adapters/webAuthn.ts +6 -6
- package/src/index.ts +1 -1
- package/src/server/Handler.test.ts +6 -6
- package/src/server/Handler.ts +3 -3
- package/dist/core/Ceremony.d.ts.map +0 -1
- package/dist/core/Ceremony.js.map +0 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -66,7 +66,7 @@ Use the `accounts/cli` entrypoint when an external CLI already owns the local ke
|
|
|
66
66
|
import { Provider } from 'accounts/cli'
|
|
67
67
|
|
|
68
68
|
const provider = Provider.create({
|
|
69
|
-
|
|
69
|
+
host: 'https://wallet.example.com/cli-auth',
|
|
70
70
|
})
|
|
71
71
|
|
|
72
72
|
const { accounts } = await provider.request({
|
|
@@ -2,7 +2,7 @@ import type { Hex } from 'viem';
|
|
|
2
2
|
import { Authentication, Registration } from 'webauthx/server';
|
|
3
3
|
import * as Storage from './Storage.js';
|
|
4
4
|
/** Pluggable strategy for WebAuthn registration and authentication ceremonies. */
|
|
5
|
-
export type
|
|
5
|
+
export type WebAuthnCeremony = {
|
|
6
6
|
/** Get credential creation options for `navigator.credentials.create()`. */
|
|
7
7
|
getRegistrationOptions: (params: getRegistrationOptions.Parameters) => Promise<getRegistrationOptions.ReturnType>;
|
|
8
8
|
/** Verify a registration response and extract the public key. */
|
|
@@ -62,8 +62,8 @@ export declare namespace verifyAuthentication {
|
|
|
62
62
|
userId?: string | undefined;
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
|
-
/** Creates a {@link
|
|
66
|
-
export declare function from(ceremony:
|
|
65
|
+
/** Creates a {@link WebAuthnCeremony} from a custom implementation. */
|
|
66
|
+
export declare function from(ceremony: WebAuthnCeremony): WebAuthnCeremony;
|
|
67
67
|
/**
|
|
68
68
|
* Creates a pure client-side ceremony for development and prototyping.
|
|
69
69
|
*
|
|
@@ -72,12 +72,12 @@ export declare function from(ceremony: Ceremony): Ceremony;
|
|
|
72
72
|
*
|
|
73
73
|
* @example
|
|
74
74
|
* ```ts
|
|
75
|
-
* import {
|
|
75
|
+
* import { WebAuthnCeremony } from 'accounts'
|
|
76
76
|
*
|
|
77
|
-
* const ceremony =
|
|
77
|
+
* const ceremony = WebAuthnCeremony.local()
|
|
78
78
|
* ```
|
|
79
79
|
*/
|
|
80
|
-
export declare function local(options?: local.Options):
|
|
80
|
+
export declare function local(options?: local.Options): WebAuthnCeremony;
|
|
81
81
|
export declare namespace local {
|
|
82
82
|
type Options = {
|
|
83
83
|
/** Relying Party ID (e.g. `"example.com"`). @default location.hostname */
|
|
@@ -87,23 +87,23 @@ export declare namespace local {
|
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
89
|
/**
|
|
90
|
-
* Creates a server-backed ceremony that delegates to a remote {@link Handler.
|
|
90
|
+
* Creates a server-backed ceremony that delegates to a remote {@link Handler.webAuthn} endpoint.
|
|
91
91
|
*
|
|
92
92
|
* All challenge generation, verification, and credential storage happen server-side.
|
|
93
93
|
* The client uses `fetch()` to communicate with 4 POST endpoints derived from the base URL.
|
|
94
94
|
*
|
|
95
95
|
* @example
|
|
96
96
|
* ```ts
|
|
97
|
-
* import {
|
|
97
|
+
* import { WebAuthnCeremony } from 'accounts'
|
|
98
98
|
*
|
|
99
|
-
* const ceremony =
|
|
99
|
+
* const ceremony = WebAuthnCeremony.server({ url: 'https://example.com/webauthn' })
|
|
100
100
|
* ```
|
|
101
101
|
*/
|
|
102
|
-
export declare function server(options: server.Options):
|
|
102
|
+
export declare function server(options: server.Options): WebAuthnCeremony;
|
|
103
103
|
export declare namespace server {
|
|
104
104
|
type Options = {
|
|
105
105
|
/** Base URL of the WebAuthn handler (e.g. `"https://example.com/webauthn"`). */
|
|
106
106
|
url: string;
|
|
107
107
|
};
|
|
108
108
|
}
|
|
109
|
-
//# sourceMappingURL=
|
|
109
|
+
//# sourceMappingURL=WebAuthnCeremony.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebAuthnCeremony.d.ts","sourceRoot":"","sources":["../../src/core/WebAuthnCeremony.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Bytes } from 'ox';
|
|
2
2
|
import { Authentication, Registration } from 'webauthx/server';
|
|
3
3
|
import * as Storage from './Storage.js';
|
|
4
|
-
/** Creates a {@link
|
|
4
|
+
/** Creates a {@link WebAuthnCeremony} from a custom implementation. */
|
|
5
5
|
export function from(ceremony) {
|
|
6
6
|
return ceremony;
|
|
7
7
|
}
|
|
@@ -13,9 +13,9 @@ export function from(ceremony) {
|
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
15
15
|
* ```ts
|
|
16
|
-
* import {
|
|
16
|
+
* import { WebAuthnCeremony } from 'accounts'
|
|
17
17
|
*
|
|
18
|
-
* const ceremony =
|
|
18
|
+
* const ceremony = WebAuthnCeremony.local()
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
21
|
export function local(options = {}) {
|
|
@@ -59,16 +59,16 @@ export function local(options = {}) {
|
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
62
|
-
* Creates a server-backed ceremony that delegates to a remote {@link Handler.
|
|
62
|
+
* Creates a server-backed ceremony that delegates to a remote {@link Handler.webAuthn} endpoint.
|
|
63
63
|
*
|
|
64
64
|
* All challenge generation, verification, and credential storage happen server-side.
|
|
65
65
|
* The client uses `fetch()` to communicate with 4 POST endpoints derived from the base URL.
|
|
66
66
|
*
|
|
67
67
|
* @example
|
|
68
68
|
* ```ts
|
|
69
|
-
* import {
|
|
69
|
+
* import { WebAuthnCeremony } from 'accounts'
|
|
70
70
|
*
|
|
71
|
-
* const ceremony =
|
|
71
|
+
* const ceremony = WebAuthnCeremony.server({ url: 'https://example.com/webauthn' })
|
|
72
72
|
* ```
|
|
73
73
|
*/
|
|
74
74
|
export function server(options) {
|
|
@@ -101,4 +101,4 @@ export function server(options) {
|
|
|
101
101
|
},
|
|
102
102
|
});
|
|
103
103
|
}
|
|
104
|
-
//# sourceMappingURL=
|
|
104
|
+
//# sourceMappingURL=WebAuthnCeremony.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebAuthnCeremony.js","sourceRoot":"","sources":["../../src/core/WebAuthnCeremony.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,CAAA;AAE1B,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9D,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAyEvC,uEAAuE;AACvE,MAAM,UAAU,IAAI,CAAC,QAA0B;IAC7C,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,KAAK,CAAC,UAAyB,EAAE;IAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAA;IAChG,MAAM,OAAO,GACX,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACvF,MAAM,UAAU,GAAG,aAAa,CAAA;IAEhC,OAAO,IAAI,CAAC;QACV,KAAK,CAAC,sBAAsB,CAAC,UAAU;YACrC,MAAM,EAAE,oBAAoB,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;YACzD,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,UAAU,CAAC;gBAC1C,oBAAoB,EAAE,oBAA4C;gBAClE,IAAI;gBACJ,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;gBAC5B,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS;aAClE,CAAC,CAAA;YACF,OAAO,EAAE,OAAO,EAAE,CAAA;QACpB,CAAC;QAED,KAAK,CAAC,kBAAkB,CAAC,UAAU;YACjC,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAA;YACtC,MAAM,WAAW,GAAG,CAAC,MAAM,OAAO,CAAC,OAAO,CAAsB,UAAU,CAAC,CAAC,IAAI,EAAE,CAAA;YAClF,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,SAAS,CAAA;YACtC,MAAM,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;YAC9C,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,CAAA;QACnD,CAAC;QAED,KAAK,CAAC,wBAAwB,CAAC,UAAU,GAAG,EAAE;YAC5C,MAAM,EAAE,kBAAkB,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,UAAU,CAAA;YAClE,MAAM,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC,UAAU,CAAC;gBAC5C,SAAS;gBACT,YAAY,EAAG,kBAA2C,IAAI,YAAY;gBAC1E,IAAI;aACL,CAAC,CAAA;YACF,OAAO,EAAE,OAAO,EAAE,CAAA;QACpB,CAAC;QAED,KAAK,CAAC,oBAAoB,CAAC,QAAQ;YACjC,MAAM,WAAW,GAAG,CAAC,MAAM,OAAO,CAAC,OAAO,CAAsB,UAAU,CAAC,CAAC,IAAI,EAAE,CAAA;YAClF,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;YAC1C,IAAI,CAAC,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAA;YACrE,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,CAAA;QACjD,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAWD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,MAAM,CAAC,OAAuB;IAC5C,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAA;IAEvB,KAAK,UAAU,OAAO,CAAa,IAAY,EAAE,IAAa;QAC5D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,GAAG,GAAG,IAAI,EAAE,EAAE;YAC5C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAA;QACF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAClC,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAE,IAA2B,CAAC,KAAK,IAAI,gBAAgB,CAAC,CAAA;QACzF,OAAO,IAAkB,CAAA;IAC3B,CAAC;IAED,OAAO,IAAI,CAAC;QACV,KAAK,CAAC,sBAAsB,CAAC,UAAU;YACrC,MAAM,EAAE,oBAAoB,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;YACzD,OAAO,OAAO,CAAC,mBAAmB,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;QAC7E,CAAC;QAED,KAAK,CAAC,kBAAkB,CAAC,UAAU;YACjC,OAAO,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,CAAA;QACzC,CAAC;QAED,KAAK,CAAC,wBAAwB,CAAC,UAAU,GAAG,EAAE;YAC5C,MAAM,EAAE,kBAAkB,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,UAAU,CAAA;YAC7E,OAAO,OAAO,CAAC,gBAAgB,EAAE,EAAE,kBAAkB,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,CAAA;QAC9F,CAAC;QAED,KAAK,CAAC,oBAAoB,CAAC,QAAQ;YACjC,OAAO,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QACpC,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { OneOf } from '../../internal/types.js';
|
|
2
2
|
import * as Adapter from '../Adapter.js';
|
|
3
|
-
import * as
|
|
3
|
+
import * as WebAuthnCeremony from '../WebAuthnCeremony.js';
|
|
4
4
|
/**
|
|
5
5
|
* Creates a WebAuthn adapter backed by real passkey ceremonies.
|
|
6
6
|
*
|
|
7
7
|
* Wraps the {@link local} adapter with WebAuthn registration and authentication flows,
|
|
8
|
-
* using the provided {@link
|
|
8
|
+
* using the provided {@link WebAuthnCeremony} for challenge generation and verification.
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
11
|
* ```ts
|
|
@@ -19,10 +19,10 @@ import * as Ceremony from '../Ceremony.js';
|
|
|
19
19
|
export declare function webAuthn(options?: webAuthn.Options): Adapter.Adapter;
|
|
20
20
|
export declare namespace webAuthn {
|
|
21
21
|
type Options = OneOf<{
|
|
22
|
-
/** Ceremony strategy for WebAuthn registration and authentication. @default
|
|
23
|
-
ceremony?:
|
|
22
|
+
/** Ceremony strategy for WebAuthn registration and authentication. @default WebAuthnCeremony.local() */
|
|
23
|
+
ceremony?: WebAuthnCeremony.WebAuthnCeremony | undefined;
|
|
24
24
|
} | {
|
|
25
|
-
/** URL of a WebAuthn handler (shorthand for `
|
|
25
|
+
/** URL of a WebAuthn handler (shorthand for `WebAuthnCeremony.server({ url })`). */
|
|
26
26
|
authUrl?: string | undefined;
|
|
27
27
|
}> & {
|
|
28
28
|
/** Data URI of the provider icon. @default Black 1×1 SVG. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webAuthn.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/webAuthn.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AACxC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"webAuthn.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/webAuthn.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AACxC,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAA;AAG1D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,OAAO,GAAE,QAAQ,CAAC,OAAY,GAAG,OAAO,CAAC,OAAO,CAmFxE;AAED,MAAM,CAAC,OAAO,WAAW,QAAQ,CAAC;IAChC,KAAK,OAAO,GAAG,KAAK,CAChB;QACE,wGAAwG;QACxG,QAAQ,CAAC,EAAE,gBAAgB,CAAC,gBAAgB,GAAG,SAAS,CAAA;KACzD,GACD;QACE,oFAAoF;QACpF,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAC7B,CACJ,GAAG;QACF,6DAA6D;QAC7D,IAAI,CAAC,EAAE,cAAc,MAAM,EAAE,GAAG,SAAS,CAAA;QACzC,oFAAoF;QACpF,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QACzB,8DAA8D;QAC9D,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAC1B,CAAA;CACF"}
|
|
@@ -3,13 +3,13 @@ import { SignatureEnvelope } from 'ox/tempo';
|
|
|
3
3
|
import { Account } from 'viem/tempo';
|
|
4
4
|
import { Authentication, Registration } from 'webauthx/client';
|
|
5
5
|
import * as Adapter from '../Adapter.js';
|
|
6
|
-
import * as
|
|
6
|
+
import * as WebAuthnCeremony from '../WebAuthnCeremony.js';
|
|
7
7
|
import { local } from './local.js';
|
|
8
8
|
/**
|
|
9
9
|
* Creates a WebAuthn adapter backed by real passkey ceremonies.
|
|
10
10
|
*
|
|
11
11
|
* Wraps the {@link local} adapter with WebAuthn registration and authentication flows,
|
|
12
|
-
* using the provided {@link
|
|
12
|
+
* using the provided {@link WebAuthnCeremony} for challenge generation and verification.
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
15
15
|
* ```ts
|
|
@@ -25,7 +25,7 @@ export function webAuthn(options = {}) {
|
|
|
25
25
|
return Adapter.define({ icon, name, rdns }, (parameters) => {
|
|
26
26
|
const { storage } = parameters;
|
|
27
27
|
const ceremony = options.ceremony ??
|
|
28
|
-
(authUrl ?
|
|
28
|
+
(authUrl ? WebAuthnCeremony.server({ url: authUrl }) : WebAuthnCeremony.local({ storage }));
|
|
29
29
|
const base = local({
|
|
30
30
|
async createAccount(parameters) {
|
|
31
31
|
const { options } = await ceremony.getRegistrationOptions(parameters);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webAuthn.js","sourceRoot":"","sources":["../../../src/core/adapters/webAuthn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,IAAI,CAAA;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAG9D,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AACxC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"webAuthn.js","sourceRoot":"","sources":["../../../src/core/adapters/webAuthn.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * as Ceremony from './core/Ceremony.js';
|
|
2
1
|
export * as IntersectionObserver from './core/IntersectionObserver.js';
|
|
3
2
|
export * as Dialog from './core/Dialog.js';
|
|
4
3
|
export * as Messenger from './core/Messenger.js';
|
|
@@ -10,6 +9,7 @@ export * as Rpc from './core/zod/rpc.js';
|
|
|
10
9
|
export * as Store from './core/Store.js';
|
|
11
10
|
export * as Storage from './core/Storage.js';
|
|
12
11
|
export * as TrustedHosts from './core/TrustedHosts.js';
|
|
12
|
+
export * as WebAuthnCeremony from './core/WebAuthnCeremony.js';
|
|
13
13
|
export { dialog, dialog as tempoWallet } from './core/adapters/dialog.js';
|
|
14
14
|
export { local } from './core/adapters/local.js';
|
|
15
15
|
export { webAuthn } from './core/adapters/webAuthn.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,oBAAoB,MAAM,gCAAgC,CAAA;AACtE,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAA;AAC1C,OAAO,KAAK,SAAS,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAA;AAC1C,OAAO,KAAK,QAAQ,MAAM,oBAAoB,CAAA;AAC9C,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAA;AAC1C,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAA;AAC1C,OAAO,KAAK,GAAG,MAAM,mBAAmB,CAAA;AACxC,OAAO,KAAK,KAAK,MAAM,iBAAiB,CAAA;AACxC,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAA;AAC5C,OAAO,KAAK,YAAY,MAAM,wBAAwB,CAAA;AACtD,OAAO,KAAK,gBAAgB,MAAM,4BAA4B,CAAA;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,2BAA2B,CAAA;AACzE,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * as Ceremony from './core/Ceremony.js';
|
|
2
1
|
export * as IntersectionObserver from './core/IntersectionObserver.js';
|
|
3
2
|
export * as Dialog from './core/Dialog.js';
|
|
4
3
|
export * as Messenger from './core/Messenger.js';
|
|
@@ -10,6 +9,7 @@ export * as Rpc from './core/zod/rpc.js';
|
|
|
10
9
|
export * as Store from './core/Store.js';
|
|
11
10
|
export * as Storage from './core/Storage.js';
|
|
12
11
|
export * as TrustedHosts from './core/TrustedHosts.js';
|
|
12
|
+
export * as WebAuthnCeremony from './core/WebAuthnCeremony.js';
|
|
13
13
|
export { dialog, dialog as tempoWallet } from './core/adapters/dialog.js';
|
|
14
14
|
export { local } from './core/adapters/local.js';
|
|
15
15
|
export { webAuthn } from './core/adapters/webAuthn.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,oBAAoB,MAAM,gCAAgC,CAAA;AACtE,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAA;AAC1C,OAAO,KAAK,SAAS,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAA;AAC1C,OAAO,KAAK,QAAQ,MAAM,oBAAoB,CAAA;AAC9C,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAA;AAC1C,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAA;AAC1C,OAAO,KAAK,GAAG,MAAM,mBAAmB,CAAA;AACxC,OAAO,KAAK,KAAK,MAAM,iBAAiB,CAAA;AACxC,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAA;AAC5C,OAAO,KAAK,YAAY,MAAM,wBAAwB,CAAA;AACtD,OAAO,KAAK,gBAAgB,MAAM,4BAA4B,CAAA;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,2BAA2B,CAAA;AACzE,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAA"}
|
package/dist/server/Handler.d.ts
CHANGED
|
@@ -248,7 +248,7 @@ export declare namespace codeAuth {
|
|
|
248
248
|
* ```ts
|
|
249
249
|
* import { Handler, Kv } from 'accounts/server'
|
|
250
250
|
*
|
|
251
|
-
* const handler = Handler.
|
|
251
|
+
* const handler = Handler.webAuthn({
|
|
252
252
|
* kv: Kv.memory(),
|
|
253
253
|
* origin: 'https://example.com',
|
|
254
254
|
* rpId: 'example.com',
|
|
@@ -260,8 +260,8 @@ export declare namespace codeAuth {
|
|
|
260
260
|
* @param options - Options.
|
|
261
261
|
* @returns Request handler.
|
|
262
262
|
*/
|
|
263
|
-
export declare function
|
|
264
|
-
export declare namespace
|
|
263
|
+
export declare function webAuthn(options: webAuthn.Options): Handler;
|
|
264
|
+
export declare namespace webAuthn {
|
|
265
265
|
type Options = from.Options & {
|
|
266
266
|
/** Maximum age of a challenge in seconds before it expires. @default 300 */
|
|
267
267
|
challengeTtl?: number | undefined;
|
package/dist/server/Handler.js
CHANGED
|
@@ -343,7 +343,7 @@ export function codeAuth(options = {}) {
|
|
|
343
343
|
* ```ts
|
|
344
344
|
* import { Handler, Kv } from 'accounts/server'
|
|
345
345
|
*
|
|
346
|
-
* const handler = Handler.
|
|
346
|
+
* const handler = Handler.webAuthn({
|
|
347
347
|
* kv: Kv.memory(),
|
|
348
348
|
* origin: 'https://example.com',
|
|
349
349
|
* rpId: 'example.com',
|
|
@@ -355,7 +355,7 @@ export function codeAuth(options = {}) {
|
|
|
355
355
|
* @param options - Options.
|
|
356
356
|
* @returns Request handler.
|
|
357
357
|
*/
|
|
358
|
-
export function
|
|
358
|
+
export function webAuthn(options) {
|
|
359
359
|
const { challengeTtl = 300, kv, onAuthenticate, onRegister, path = '', rpId, ...rest } = options;
|
|
360
360
|
const origin = options.origin;
|
|
361
361
|
const router = from(rest);
|
package/package.json
CHANGED
|
@@ -8,12 +8,12 @@ import { describe, expect, test } from 'vp/test'
|
|
|
8
8
|
import { accounts, chain, getClient } from '../../test/config.js'
|
|
9
9
|
import { url as webauthnUrl } from '../../test/webauthn.constants.js'
|
|
10
10
|
import { webAuthn } from './adapters/webAuthn.js'
|
|
11
|
-
import * as Ceremony from './Ceremony.js'
|
|
12
11
|
import * as Expiry from './Expiry.js'
|
|
13
12
|
import * as Provider from './Provider.js'
|
|
14
13
|
import * as Storage from './Storage.js'
|
|
14
|
+
import * as WebAuthnCeremony from './WebAuthnCeremony.js'
|
|
15
15
|
|
|
16
|
-
const ceremony =
|
|
16
|
+
const ceremony = WebAuthnCeremony.server({ url: webauthnUrl })
|
|
17
17
|
|
|
18
18
|
function getProvider(options: Partial<Provider.create.Options> = {}) {
|
|
19
19
|
return Provider.create({
|
|
@@ -3,13 +3,13 @@ import { Registration, Authentication } from 'webauthx/client'
|
|
|
3
3
|
|
|
4
4
|
import { hooksUrl, url as webauthnUrl } from '../../test/webauthn.constants.js'
|
|
5
5
|
import { webAuthn } from './adapters/webAuthn.js'
|
|
6
|
-
import * as Ceremony from './Ceremony.js'
|
|
7
6
|
import * as Provider from './Provider.js'
|
|
8
7
|
import * as Storage from './Storage.js'
|
|
8
|
+
import * as WebAuthnCeremony from './WebAuthnCeremony.js'
|
|
9
9
|
|
|
10
10
|
describe('local', () => {
|
|
11
11
|
test('default: creates a passkey and verifies registration', async () => {
|
|
12
|
-
const ceremony =
|
|
12
|
+
const ceremony = WebAuthnCeremony.local()
|
|
13
13
|
const { options } = await ceremony.getRegistrationOptions({ name: 'Test' })
|
|
14
14
|
const credential = await Registration.create({ options })
|
|
15
15
|
const result = await ceremony.verifyRegistration(credential)
|
|
@@ -19,7 +19,7 @@ describe('local', () => {
|
|
|
19
19
|
})
|
|
20
20
|
|
|
21
21
|
test('behavior: authenticates with an existing passkey', async () => {
|
|
22
|
-
const ceremony =
|
|
22
|
+
const ceremony = WebAuthnCeremony.local()
|
|
23
23
|
const { options: regOptions } = await ceremony.getRegistrationOptions({ name: 'Test' })
|
|
24
24
|
const credential = await Registration.create({ options: regOptions })
|
|
25
25
|
const { publicKey } = await ceremony.verifyRegistration(credential)
|
|
@@ -35,7 +35,7 @@ describe('local', () => {
|
|
|
35
35
|
})
|
|
36
36
|
|
|
37
37
|
test('behavior: register → authenticate → publicKeys match', async () => {
|
|
38
|
-
const ceremony =
|
|
38
|
+
const ceremony = WebAuthnCeremony.local()
|
|
39
39
|
const { options: regOptions } = await ceremony.getRegistrationOptions({ name: 'Round-trip' })
|
|
40
40
|
const credential = await Registration.create({ options: regOptions })
|
|
41
41
|
const reg = await ceremony.verifyRegistration(credential)
|
|
@@ -52,7 +52,7 @@ describe('local', () => {
|
|
|
52
52
|
})
|
|
53
53
|
|
|
54
54
|
describe('server', () => {
|
|
55
|
-
const ceremony =
|
|
55
|
+
const ceremony = WebAuthnCeremony.server({ url: webauthnUrl })
|
|
56
56
|
|
|
57
57
|
test('default: register → verify returns valid publicKey hex', async () => {
|
|
58
58
|
const { options } = await ceremony.getRegistrationOptions({ name: 'Server Test' })
|
|
@@ -127,7 +127,7 @@ describe('server', () => {
|
|
|
127
127
|
})
|
|
128
128
|
|
|
129
129
|
describe('server (provider round-trip)', () => {
|
|
130
|
-
const ceremony =
|
|
130
|
+
const ceremony = WebAuthnCeremony.server({ url: webauthnUrl })
|
|
131
131
|
|
|
132
132
|
function createProvider() {
|
|
133
133
|
return Provider.create({
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { describe, expect, test } from 'vp/test'
|
|
2
2
|
|
|
3
|
-
import * as
|
|
3
|
+
import * as WebAuthnCeremony from './WebAuthnCeremony.js'
|
|
4
4
|
|
|
5
5
|
describe('from', () => {
|
|
6
6
|
test('default: returns the ceremony', () => {
|
|
7
|
-
const ceremony =
|
|
7
|
+
const ceremony = WebAuthnCeremony.from({
|
|
8
8
|
getRegistrationOptions: async () => ({ options: {} as any }),
|
|
9
9
|
verifyRegistration: async () => ({ credentialId: 'cred-1', publicKey: '0x1234' }),
|
|
10
10
|
getAuthenticationOptions: async () => ({ options: {} as any }),
|
|
@@ -20,12 +20,12 @@ describe('from', () => {
|
|
|
20
20
|
|
|
21
21
|
describe('local', () => {
|
|
22
22
|
test('default: creates a ceremony', () => {
|
|
23
|
-
const ceremony =
|
|
23
|
+
const ceremony = WebAuthnCeremony.local({ rpId: 'example.com' })
|
|
24
24
|
expect(ceremony).toBeDefined()
|
|
25
25
|
})
|
|
26
26
|
|
|
27
27
|
test('behavior: getRegistrationOptions returns serialized options', async () => {
|
|
28
|
-
const ceremony =
|
|
28
|
+
const ceremony = WebAuthnCeremony.local({ rpId: 'example.com' })
|
|
29
29
|
|
|
30
30
|
const { options } = await ceremony.getRegistrationOptions({ name: 'Test' })
|
|
31
31
|
expect(options.publicKey).toBeDefined()
|
|
@@ -36,7 +36,7 @@ describe('local', () => {
|
|
|
36
36
|
})
|
|
37
37
|
|
|
38
38
|
test('behavior: getAuthenticationOptions returns serialized options', async () => {
|
|
39
|
-
const ceremony =
|
|
39
|
+
const ceremony = WebAuthnCeremony.local({ rpId: 'example.com' })
|
|
40
40
|
|
|
41
41
|
const { options } = await ceremony.getAuthenticationOptions()
|
|
42
42
|
expect(options.publicKey).toBeDefined()
|
|
@@ -45,7 +45,7 @@ describe('local', () => {
|
|
|
45
45
|
})
|
|
46
46
|
|
|
47
47
|
test('behavior: verifyRegistration stores credential and returns publicKey', async () => {
|
|
48
|
-
const ceremony =
|
|
48
|
+
const ceremony = WebAuthnCeremony.local({ rpId: 'example.com' })
|
|
49
49
|
|
|
50
50
|
const result = await ceremony.verifyRegistration({
|
|
51
51
|
attestationObject: 'mock',
|
|
@@ -70,7 +70,7 @@ describe('local', () => {
|
|
|
70
70
|
})
|
|
71
71
|
|
|
72
72
|
test('behavior: verifyAuthentication returns stored publicKey', async () => {
|
|
73
|
-
const ceremony =
|
|
73
|
+
const ceremony = WebAuthnCeremony.local({ rpId: 'example.com' })
|
|
74
74
|
|
|
75
75
|
// Register first to store the credential
|
|
76
76
|
await ceremony.verifyRegistration({
|
|
@@ -112,7 +112,7 @@ describe('local', () => {
|
|
|
112
112
|
})
|
|
113
113
|
|
|
114
114
|
test('error: verifyAuthentication throws for unknown credential', async () => {
|
|
115
|
-
const ceremony =
|
|
115
|
+
const ceremony = WebAuthnCeremony.local({ rpId: 'example.com' })
|
|
116
116
|
|
|
117
117
|
await expect(
|
|
118
118
|
ceremony.verifyAuthentication({
|
|
@@ -134,7 +134,7 @@ describe('local', () => {
|
|
|
134
134
|
})
|
|
135
135
|
|
|
136
136
|
test('behavior: each call to getRegistrationOptions generates a unique challenge', async () => {
|
|
137
|
-
const ceremony =
|
|
137
|
+
const ceremony = WebAuthnCeremony.local({ rpId: 'example.com' })
|
|
138
138
|
|
|
139
139
|
const { options: a } = await ceremony.getRegistrationOptions({ name: 'Test' })
|
|
140
140
|
const { options: b } = await ceremony.getRegistrationOptions({ name: 'Test' })
|
|
@@ -142,7 +142,7 @@ describe('local', () => {
|
|
|
142
142
|
})
|
|
143
143
|
|
|
144
144
|
test('behavior: each call to getAuthenticationOptions generates a unique challenge', async () => {
|
|
145
|
-
const ceremony =
|
|
145
|
+
const ceremony = WebAuthnCeremony.local({ rpId: 'example.com' })
|
|
146
146
|
|
|
147
147
|
const { options: a } = await ceremony.getAuthenticationOptions()
|
|
148
148
|
const { options: b } = await ceremony.getAuthenticationOptions()
|
|
@@ -5,7 +5,7 @@ import { Authentication, Registration } from 'webauthx/server'
|
|
|
5
5
|
import * as Storage from './Storage.js'
|
|
6
6
|
|
|
7
7
|
/** Pluggable strategy for WebAuthn registration and authentication ceremonies. */
|
|
8
|
-
export type
|
|
8
|
+
export type WebAuthnCeremony = {
|
|
9
9
|
/** Get credential creation options for `navigator.credentials.create()`. */
|
|
10
10
|
getRegistrationOptions: (
|
|
11
11
|
params: getRegistrationOptions.Parameters,
|
|
@@ -75,8 +75,8 @@ export declare namespace verifyAuthentication {
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
/** Creates a {@link
|
|
79
|
-
export function from(ceremony:
|
|
78
|
+
/** Creates a {@link WebAuthnCeremony} from a custom implementation. */
|
|
79
|
+
export function from(ceremony: WebAuthnCeremony): WebAuthnCeremony {
|
|
80
80
|
return ceremony
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -88,12 +88,12 @@ export function from(ceremony: Ceremony): Ceremony {
|
|
|
88
88
|
*
|
|
89
89
|
* @example
|
|
90
90
|
* ```ts
|
|
91
|
-
* import {
|
|
91
|
+
* import { WebAuthnCeremony } from 'accounts'
|
|
92
92
|
*
|
|
93
|
-
* const ceremony =
|
|
93
|
+
* const ceremony = WebAuthnCeremony.local()
|
|
94
94
|
* ```
|
|
95
95
|
*/
|
|
96
|
-
export function local(options: local.Options = {}):
|
|
96
|
+
export function local(options: local.Options = {}): WebAuthnCeremony {
|
|
97
97
|
const rpId = options.rpId ?? (typeof location !== 'undefined' ? location.hostname : 'localhost')
|
|
98
98
|
const storage =
|
|
99
99
|
options.storage ?? (typeof window !== 'undefined' ? Storage.idb() : Storage.memory())
|
|
@@ -148,19 +148,19 @@ export declare namespace local {
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
/**
|
|
151
|
-
* Creates a server-backed ceremony that delegates to a remote {@link Handler.
|
|
151
|
+
* Creates a server-backed ceremony that delegates to a remote {@link Handler.webAuthn} endpoint.
|
|
152
152
|
*
|
|
153
153
|
* All challenge generation, verification, and credential storage happen server-side.
|
|
154
154
|
* The client uses `fetch()` to communicate with 4 POST endpoints derived from the base URL.
|
|
155
155
|
*
|
|
156
156
|
* @example
|
|
157
157
|
* ```ts
|
|
158
|
-
* import {
|
|
158
|
+
* import { WebAuthnCeremony } from 'accounts'
|
|
159
159
|
*
|
|
160
|
-
* const ceremony =
|
|
160
|
+
* const ceremony = WebAuthnCeremony.server({ url: 'https://example.com/webauthn' })
|
|
161
161
|
* ```
|
|
162
162
|
*/
|
|
163
|
-
export function server(options: server.Options):
|
|
163
|
+
export function server(options: server.Options): WebAuthnCeremony {
|
|
164
164
|
const { url } = options
|
|
165
165
|
|
|
166
166
|
async function request<returnType>(path: string, body: unknown): Promise<returnType> {
|
|
@@ -5,14 +5,14 @@ import { Authentication, Registration } from 'webauthx/client'
|
|
|
5
5
|
|
|
6
6
|
import type { OneOf } from '../../internal/types.js'
|
|
7
7
|
import * as Adapter from '../Adapter.js'
|
|
8
|
-
import * as
|
|
8
|
+
import * as WebAuthnCeremony from '../WebAuthnCeremony.js'
|
|
9
9
|
import { local } from './local.js'
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Creates a WebAuthn adapter backed by real passkey ceremonies.
|
|
13
13
|
*
|
|
14
14
|
* Wraps the {@link local} adapter with WebAuthn registration and authentication flows,
|
|
15
|
-
* using the provided {@link
|
|
15
|
+
* using the provided {@link WebAuthnCeremony} for challenge generation and verification.
|
|
16
16
|
*
|
|
17
17
|
* @example
|
|
18
18
|
* ```ts
|
|
@@ -31,7 +31,7 @@ export function webAuthn(options: webAuthn.Options = {}): Adapter.Adapter {
|
|
|
31
31
|
|
|
32
32
|
const ceremony =
|
|
33
33
|
options.ceremony ??
|
|
34
|
-
(authUrl ?
|
|
34
|
+
(authUrl ? WebAuthnCeremony.server({ url: authUrl }) : WebAuthnCeremony.local({ storage }))
|
|
35
35
|
|
|
36
36
|
const base = local({
|
|
37
37
|
async createAccount(parameters) {
|
|
@@ -111,11 +111,11 @@ export function webAuthn(options: webAuthn.Options = {}): Adapter.Adapter {
|
|
|
111
111
|
export declare namespace webAuthn {
|
|
112
112
|
type Options = OneOf<
|
|
113
113
|
| {
|
|
114
|
-
/** Ceremony strategy for WebAuthn registration and authentication. @default
|
|
115
|
-
ceremony?:
|
|
114
|
+
/** Ceremony strategy for WebAuthn registration and authentication. @default WebAuthnCeremony.local() */
|
|
115
|
+
ceremony?: WebAuthnCeremony.WebAuthnCeremony | undefined
|
|
116
116
|
}
|
|
117
117
|
| {
|
|
118
|
-
/** URL of a WebAuthn handler (shorthand for `
|
|
118
|
+
/** URL of a WebAuthn handler (shorthand for `WebAuthnCeremony.server({ url })`). */
|
|
119
119
|
authUrl?: string | undefined
|
|
120
120
|
}
|
|
121
121
|
> & {
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * as Ceremony from './core/Ceremony.js'
|
|
2
1
|
export * as IntersectionObserver from './core/IntersectionObserver.js'
|
|
3
2
|
export * as Dialog from './core/Dialog.js'
|
|
4
3
|
export * as Messenger from './core/Messenger.js'
|
|
@@ -10,6 +9,7 @@ export * as Rpc from './core/zod/rpc.js'
|
|
|
10
9
|
export * as Store from './core/Store.js'
|
|
11
10
|
export * as Storage from './core/Storage.js'
|
|
12
11
|
export * as TrustedHosts from './core/TrustedHosts.js'
|
|
12
|
+
export * as WebAuthnCeremony from './core/WebAuthnCeremony.js'
|
|
13
13
|
export { dialog, dialog as tempoWallet } from './core/adapters/dialog.js'
|
|
14
14
|
export { local } from './core/adapters/local.js'
|
|
15
15
|
export { webAuthn } from './core/adapters/webAuthn.js'
|
|
@@ -8,7 +8,7 @@ import { afterAll, afterEach, beforeAll, describe, expect, test } from 'vp/test'
|
|
|
8
8
|
|
|
9
9
|
import { accounts, chain, getClient, http } from '../../test/config.js'
|
|
10
10
|
import { createServer, type Server } from '../../test/utils.js'
|
|
11
|
-
import * as
|
|
11
|
+
import * as WebAuthnCeremony from '../core/WebAuthnCeremony.js'
|
|
12
12
|
import * as Handler from './Handler.js'
|
|
13
13
|
import * as Kv from './Kv.js'
|
|
14
14
|
|
|
@@ -849,17 +849,17 @@ describe('feePayer', () => {
|
|
|
849
849
|
|
|
850
850
|
describe('webauthn', () => {
|
|
851
851
|
let server: Server
|
|
852
|
-
let ceremony:
|
|
852
|
+
let ceremony: WebAuthnCeremony.WebAuthnCeremony
|
|
853
853
|
|
|
854
854
|
beforeAll(async () => {
|
|
855
855
|
server = await createServer(
|
|
856
|
-
Handler.
|
|
856
|
+
Handler.webAuthn({
|
|
857
857
|
kv: Kv.memory(),
|
|
858
858
|
origin: 'http://localhost',
|
|
859
859
|
rpId: 'localhost',
|
|
860
860
|
}).listener,
|
|
861
861
|
)
|
|
862
|
-
ceremony =
|
|
862
|
+
ceremony = WebAuthnCeremony.server({ url: server.url })
|
|
863
863
|
})
|
|
864
864
|
|
|
865
865
|
afterAll(async () => {
|
|
@@ -953,7 +953,7 @@ describe('webauthn', () => {
|
|
|
953
953
|
test('behavior: onRegister error does not call hook', async () => {
|
|
954
954
|
let called = false
|
|
955
955
|
const hookServer = await createServer(
|
|
956
|
-
Handler.
|
|
956
|
+
Handler.webAuthn({
|
|
957
957
|
kv: Kv.memory(),
|
|
958
958
|
origin: 'http://localhost',
|
|
959
959
|
rpId: 'localhost',
|
|
@@ -978,7 +978,7 @@ describe('webauthn', () => {
|
|
|
978
978
|
test('behavior: onAuthenticate error does not call hook', async () => {
|
|
979
979
|
let called = false
|
|
980
980
|
const hookServer = await createServer(
|
|
981
|
-
Handler.
|
|
981
|
+
Handler.webAuthn({
|
|
982
982
|
kv: Kv.memory(),
|
|
983
983
|
origin: 'http://localhost',
|
|
984
984
|
rpId: 'localhost',
|
package/src/server/Handler.ts
CHANGED
|
@@ -490,7 +490,7 @@ export declare namespace codeAuth {
|
|
|
490
490
|
* ```ts
|
|
491
491
|
* import { Handler, Kv } from 'accounts/server'
|
|
492
492
|
*
|
|
493
|
-
* const handler = Handler.
|
|
493
|
+
* const handler = Handler.webAuthn({
|
|
494
494
|
* kv: Kv.memory(),
|
|
495
495
|
* origin: 'https://example.com',
|
|
496
496
|
* rpId: 'example.com',
|
|
@@ -502,7 +502,7 @@ export declare namespace codeAuth {
|
|
|
502
502
|
* @param options - Options.
|
|
503
503
|
* @returns Request handler.
|
|
504
504
|
*/
|
|
505
|
-
export function
|
|
505
|
+
export function webAuthn(options: webAuthn.Options): Handler {
|
|
506
506
|
const { challengeTtl = 300, kv, onAuthenticate, onRegister, path = '', rpId, ...rest } = options
|
|
507
507
|
const origin = options.origin as string | string[]
|
|
508
508
|
|
|
@@ -637,7 +637,7 @@ export function webauthn(options: webauthn.Options): Handler {
|
|
|
637
637
|
return router
|
|
638
638
|
}
|
|
639
639
|
|
|
640
|
-
export declare namespace
|
|
640
|
+
export declare namespace webAuthn {
|
|
641
641
|
type Options = from.Options & {
|
|
642
642
|
/** Maximum age of a challenge in seconds before it expires. @default 300 */
|
|
643
643
|
challengeTtl?: number | undefined
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Ceremony.d.ts","sourceRoot":"","sources":["../../src/core/Ceremony.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Ceremony.js","sourceRoot":"","sources":["../../src/core/Ceremony.ts"],"names":[],"mappings":"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"}
|