electron-webauthn 1.1.0 → 1.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.
Files changed (42) hide show
  1. package/README.md +20 -1
  2. package/dist/index.d.ts +8 -3
  3. package/dist/index.js +78 -3
  4. package/package.json +15 -11
  5. package/dist/additional-objc/ASCPublicKeyCredentialDescriptor.d.ts +0 -12
  6. package/dist/additional-objc/ASCPublicKeyCredentialDescriptor.js +0 -2
  7. package/dist/create/authorization-controller.d.ts +0 -10
  8. package/dist/create/authorization-controller.js +0 -77
  9. package/dist/create/handler.d.ts +0 -43
  10. package/dist/create/handler.js +0 -224
  11. package/dist/create/internal-handler.d.ts +0 -35
  12. package/dist/create/internal-handler.js +0 -207
  13. package/dist/get/authorization-controller.d.ts +0 -5
  14. package/dist/get/authorization-controller.js +0 -37
  15. package/dist/get/handler.d.ts +0 -38
  16. package/dist/get/handler.js +0 -137
  17. package/dist/get/internal-handler.d.ts +0 -24
  18. package/dist/get/internal-handler.js +0 -169
  19. package/dist/helpers/client-data.d.ts +0 -14
  20. package/dist/helpers/client-data.js +0 -36
  21. package/dist/helpers/index.d.ts +0 -8
  22. package/dist/helpers/index.js +0 -48
  23. package/dist/helpers/objc.d.ts +0 -5
  24. package/dist/helpers/objc.js +0 -10
  25. package/dist/helpers/origin.d.ts +0 -19
  26. package/dist/helpers/origin.js +0 -106
  27. package/dist/helpers/presentation.d.ts +0 -1
  28. package/dist/helpers/presentation.js +0 -11
  29. package/dist/helpers/prf.d.ts +0 -5
  30. package/dist/helpers/prf.js +0 -5
  31. package/dist/helpers/public-key.d.ts +0 -1
  32. package/dist/helpers/public-key.js +0 -49
  33. package/dist/helpers/rpid.d.ts +0 -13
  34. package/dist/helpers/rpid.js +0 -59
  35. package/dist/helpers/types.d.ts +0 -1
  36. package/dist/helpers/types.js +0 -1
  37. package/dist/helpers/validation.d.ts +0 -3
  38. package/dist/helpers/validation.js +0 -9
  39. package/dist/list/handler.d.ts +0 -2
  40. package/dist/list/handler.js +0 -65
  41. package/dist/list/types.d.ts +0 -14
  42. package/dist/list/types.js +0 -1
package/README.md CHANGED
@@ -8,6 +8,8 @@ Add native WebAuthn/FIDO2 support to Electron on macOS using its AuthenticationS
8
8
 
9
9
  This package provides JavaScript bindings to Apple's AuthenticationServices framework, allowing you to perform WebAuthn credential creation (registration) and assertions (authentication/signing) in your Electron applications using W3C WebAuthn-compliant APIs.
10
10
 
11
+ The root `electron-webauthn` package is a cross-platform shim that lazy-loads `@electron-webauthn/macos` only on macOS. This keeps Linux/Windows packaging safe for apps that include but do not use WebAuthn outside macOS.
12
+
11
13
  > [!NOTE]
12
14
  > Although this library is called `electron-webauthn`, it can be used in Node.js and Bun projects as well, not just Electron.
13
15
 
@@ -21,6 +23,7 @@ This package provides JavaScript bindings to Apple's AuthenticationServices fram
21
23
  - Credential creation (registration) with attestation
22
24
  - Credential authentication (assertions) with existing credentials
23
25
  - Seamless integration with Electron's native window system
26
+ - Passkey listing via `listPasskeys` (macOS 13.3+)
24
27
  - PRF (Pseudo-Random Function) extension support
25
28
  - Large Blob extension support for reading/writing credential-specific data
26
29
  - User verification preference configuration (preferred, required, discouraged)
@@ -33,6 +36,8 @@ This package provides JavaScript bindings to Apple's AuthenticationServices fram
33
36
 
34
37
  ### Prerequisites
35
38
 
39
+ The following prerequisites apply when running on macOS:
40
+
36
41
  - Node.js / Bun
37
42
  - Xcode Command Line Tools (Run `xcode-select --install` to install)
38
43
  - `pkg-config` from Homebrew (Run `brew install pkgconf` to install)
@@ -83,7 +88,7 @@ This library implements the W3C WebAuthn standard using Apple's native Authentic
83
88
 
84
89
  ## Error Handling
85
90
 
86
- Both `createCredential` and `getCredential` functions return a result object with a `success` field. Always check this field:
91
+ `createCredential`, `getCredential`, and `listPasskeys` all return a result object with a `success` field. Always check this field:
87
92
 
88
93
  ```typescript
89
94
  const result = await createCredential(publicKeyOptions, additionalOptions);
@@ -118,6 +123,19 @@ if (!result.success) {
118
123
  console.log("Credential ID:", result.data.credentialId);
119
124
  ```
120
125
 
126
+ `listPasskeys` returns an `Error` object (not a string code) when unsuccessful:
127
+
128
+ ```typescript
129
+ const result = await listPasskeys("example.com");
130
+
131
+ if (!result.success) {
132
+ console.error("Failed to list passkeys:", result.error.message);
133
+ return;
134
+ }
135
+
136
+ console.log(`Found ${result.credentials.length} passkeys`);
137
+ ```
138
+
121
139
  ### Common Error Scenarios
122
140
 
123
141
  #### For Both Registration and Authentication
@@ -141,6 +159,7 @@ console.log("Credential ID:", result.data.credentialId);
141
159
 
142
160
  - ✅ WebAuthn credential creation (registration/attestation)
143
161
  - ✅ WebAuthn assertions (authentication with existing credentials)
162
+ - ✅ Passkey listing with `listPasskeys` (macOS 13.3+, requires `com.apple.developer.web-browser.public-key-credential` entitlement)
144
163
  - ✅ Cross-platform authenticators (external security keys like YubiKey)
145
164
  - ✅ Platform authenticators (Touch ID, Face ID)
146
165
  - ✅ Discoverable credentials (resident keys)
package/dist/index.d.ts CHANGED
@@ -1,3 +1,8 @@
1
- export * from "./get/handler.js";
2
- export * from "./create/handler.js";
3
- export * from "./list/handler.js";
1
+ import type { CreateCredentialResult, GetCredentialResult, ListPasskeysError, ListPasskeysResult, WebauthnCreateRequestOptions, WebauthnGetRequestOptions, WebauthnModule } from "@electron-webauthn/types";
2
+ export type { CreateCredentialErrorCodes, CreateCredentialResult, CreateCredentialSuccessData, CreateCredentialSuccessResult, CreateCredentialErrorResult, GetCredentialErrorCodes, GetCredentialResult, GetCredentialSuccessData, GetCredentialSuccessResult, GetCredentialErrorResult, ListPasskeysError, ListPasskeysResult, PasskeyCredential, WebauthnCreateRequestOptions, WebauthnGetRequestOptions, WebauthnModule, } from "@electron-webauthn/types";
3
+ type MacosLoader = () => Promise<WebauthnModule>;
4
+ export declare function createCredential(publicKeyOptions: PublicKeyCredentialCreationOptions | undefined, additionalOptions: WebauthnCreateRequestOptions): Promise<CreateCredentialResult>;
5
+ export declare function getCredential(publicKeyOptions: PublicKeyCredentialRequestOptions | undefined, additionalOptions: WebauthnGetRequestOptions): Promise<GetCredentialResult>;
6
+ export declare function listPasskeys(relyingPartyId: string): Promise<ListPasskeysResult | ListPasskeysError>;
7
+ export declare function __setMacosLoaderForTesting(loader: MacosLoader | null): void;
8
+ export declare function __setPlatformForTesting(platform: NodeJS.Platform | null): void;
package/dist/index.js CHANGED
@@ -1,3 +1,78 @@
1
- export * from "./get/handler.js";
2
- export * from "./create/handler.js";
3
- export * from "./list/handler.js";
1
+ const unsupportedGetResult = {
2
+ success: false,
3
+ error: "NotAllowedError",
4
+ errorObject: new Error("electron-webauthn is only available on macOS. Install @electron-webauthn/macos on Darwin hosts."),
5
+ };
6
+ const unsupportedCreateResult = {
7
+ success: false,
8
+ error: "NotAllowedError",
9
+ errorObject: new Error("electron-webauthn is only available on macOS. Install @electron-webauthn/macos on Darwin hosts."),
10
+ };
11
+ const unsupportedListResult = {
12
+ success: false,
13
+ error: new Error("electron-webauthn is only available on macOS. Install @electron-webauthn/macos on Darwin hosts."),
14
+ };
15
+ let moduleCache = null;
16
+ let modulePromise = null;
17
+ let platformOverride = null;
18
+ const defaultLoader = () => import("@electron-webauthn/macos");
19
+ let macosLoader = defaultLoader;
20
+ function runtimePlatform() {
21
+ return platformOverride ?? process.platform;
22
+ }
23
+ async function getMacosModule() {
24
+ if (runtimePlatform() !== "darwin") {
25
+ return null;
26
+ }
27
+ if (moduleCache) {
28
+ return moduleCache;
29
+ }
30
+ if (modulePromise) {
31
+ return modulePromise;
32
+ }
33
+ modulePromise = (async () => {
34
+ try {
35
+ const module = await macosLoader();
36
+ moduleCache = module;
37
+ return module;
38
+ }
39
+ catch {
40
+ return null;
41
+ }
42
+ finally {
43
+ modulePromise = null;
44
+ }
45
+ })();
46
+ return modulePromise;
47
+ }
48
+ export async function createCredential(publicKeyOptions, additionalOptions) {
49
+ const module = await getMacosModule();
50
+ if (!module) {
51
+ return unsupportedCreateResult;
52
+ }
53
+ return module.createCredential(publicKeyOptions, additionalOptions);
54
+ }
55
+ export async function getCredential(publicKeyOptions, additionalOptions) {
56
+ const module = await getMacosModule();
57
+ if (!module) {
58
+ return unsupportedGetResult;
59
+ }
60
+ return module.getCredential(publicKeyOptions, additionalOptions);
61
+ }
62
+ export async function listPasskeys(relyingPartyId) {
63
+ const module = await getMacosModule();
64
+ if (!module) {
65
+ return unsupportedListResult;
66
+ }
67
+ return module.listPasskeys(relyingPartyId);
68
+ }
69
+ export function __setMacosLoaderForTesting(loader) {
70
+ macosLoader = loader ?? defaultLoader;
71
+ moduleCache = null;
72
+ modulePromise = null;
73
+ }
74
+ export function __setPlatformForTesting(platform) {
75
+ platformOverride = platform;
76
+ moduleCache = null;
77
+ modulePromise = null;
78
+ }
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "electron-webauthn",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "repository": "https://github.com/iamEvanYT/electron-webauthn.git",
5
5
  "homepage": "https://github.com/iamEvanYT/electron-webauthn#readme",
6
- "description": "Add support for WebAuthn for Electron.",
6
+ "description": "Cross-platform loader for native WebAuthn support on macOS.",
7
7
  "main": "dist/index.js",
8
8
  "module": "dist/index.js",
9
9
  "types": "dist/index.d.ts",
@@ -15,12 +15,18 @@
15
15
  }
16
16
  },
17
17
  "files": [
18
- "dist/"
18
+ "dist",
19
+ "dist/**"
19
20
  ],
20
21
  "type": "module",
22
+ "workspaces": [
23
+ "packages/*"
24
+ ],
21
25
  "scripts": {
22
- "build": "rm -rf dist && tsc && rm -rf dist/test",
23
- "test": "bun run src/test/index.ts"
26
+ "build": "rm -rf dist && tsc -p tsconfig.json",
27
+ "build:macos": "cd packages/macos && bun run build",
28
+ "build:all": "bun run build && bun run build:macos",
29
+ "test": "bun test"
24
30
  },
25
31
  "devDependencies": {
26
32
  "@types/bun": "latest"
@@ -29,11 +35,9 @@
29
35
  "typescript": "^5"
30
36
  },
31
37
  "dependencies": {
32
- "@oslojs/webauthn": "^1.0.0",
33
- "objc-js": "^1.3.0",
34
- "objcjs-types": "^0.5.0"
38
+ "@electron-webauthn/types": "^1.2.0"
35
39
  },
36
- "trustedDependencies": [
37
- "objc-js"
38
- ]
40
+ "optionalDependencies": {
41
+ "@electron-webauthn/macos": "^1.2.0"
42
+ }
39
43
  }
@@ -1,12 +0,0 @@
1
- import type { _NSArray, _NSData, _NSObject, _NSSecureCoding } from "objcjs-types/Foundation";
2
- export declare class _ASCPublicKeyCredentialDescriptor extends _NSObject {
3
- static alloc(): _ASCPublicKeyCredentialDescriptor;
4
- static new(): _ASCPublicKeyCredentialDescriptor;
5
- init(): _ASCPublicKeyCredentialDescriptor;
6
- initWithCredentialID$transports$(credentialID: _NSData, allowedTransports: _NSArray | null): _ASCPublicKeyCredentialDescriptor;
7
- credentialID(): _NSData;
8
- transports(): _NSArray | null;
9
- }
10
- export interface _ASCPublicKeyCredentialDescriptor extends _NSSecureCoding {
11
- }
12
- export declare const ASCPublicKeyCredentialDescriptor: typeof _ASCPublicKeyCredentialDescriptor;
@@ -1,2 +0,0 @@
1
- import { AuthenticationServices } from "objcjs-types/AuthenticationServices";
2
- export const ASCPublicKeyCredentialDescriptor = AuthenticationServices.ASCPublicKeyCredentialDescriptor;
@@ -1,10 +0,0 @@
1
- import { NobjcObject } from "objc-js";
2
- import type { ExcludeCredential } from "./internal-handler.js";
3
- import type { ASAuthorizationController } from "objcjs-types/AuthenticationServices";
4
- export interface PublicKeyCredentialParams {
5
- type: "public-key";
6
- algorithm: number;
7
- }
8
- export declare function setControllerState(self: NobjcObject, clientDataHash: Buffer, pubKeyCredParams: PublicKeyCredentialParams[], residentKeyRequired: boolean, excludeCredentialIds: ExcludeCredential[]): void;
9
- export declare function removeControllerState(self: NobjcObject): void;
10
- export declare const WebauthnCreateController: typeof ASAuthorizationController;
@@ -1,77 +0,0 @@
1
- import { NobjcClass, NobjcObject, getPointer } from "objc-js";
2
- import { NSDataFromBuffer } from "objcjs-types/nsdata";
3
- import { NSArrayFromObjects, NSStringFromString } from "objcjs-types/helpers";
4
- import { NSNumber } from "objcjs-types/Foundation";
5
- import { ASCPublicKeyCredentialDescriptor } from "../additional-objc/ASCPublicKeyCredentialDescriptor.js";
6
- const createControllerState = new Map();
7
- function getObjectPointerString(self) {
8
- return getPointer(self).toString("base64");
9
- }
10
- export function setControllerState(self, clientDataHash, pubKeyCredParams, residentKeyRequired, excludeCredentialIds) {
11
- const selfPointer = getObjectPointerString(self);
12
- createControllerState.set(selfPointer, [
13
- clientDataHash,
14
- pubKeyCredParams,
15
- residentKeyRequired,
16
- excludeCredentialIds,
17
- ]);
18
- }
19
- export function removeControllerState(self) {
20
- const selfPointer = getObjectPointerString(self);
21
- createControllerState.delete(selfPointer);
22
- }
23
- export const WebauthnCreateController = NobjcClass.define({
24
- name: "WebauthnCreateController",
25
- superclass: "ASAuthorizationController",
26
- methods: {
27
- _requestContextWithRequests$error$: {
28
- types: "@@:@^@",
29
- implementation: (self, requests, outError) => {
30
- const context = NobjcClass.super(self, "_requestContextWithRequests$error$", requests, outError);
31
- const selfPointer = getObjectPointerString(self);
32
- if (context && createControllerState.has(selfPointer)) {
33
- let isSecurityKey = false;
34
- let registrationOptions = context.platformKeyCredentialCreationOptions();
35
- if (!registrationOptions) {
36
- registrationOptions =
37
- context.securityKeyCredentialCreationOptions();
38
- isSecurityKey = true;
39
- }
40
- const [clientDataHash, pubKeyCredParams, residentKeyRequired, excludeCredentials,] = createControllerState.get(selfPointer);
41
- registrationOptions.setClientDataHash$(NSDataFromBuffer(clientDataHash));
42
- registrationOptions.setChallenge$(null);
43
- const supportedAlgos = [];
44
- for (const param of pubKeyCredParams) {
45
- if (param.type === "public-key") {
46
- const nsNum = NSNumber.numberWithInteger$(param.algorithm);
47
- supportedAlgos.push(nsNum);
48
- }
49
- }
50
- if (supportedAlgos.length > 0) {
51
- registrationOptions.setSupportedAlgorithmIdentifiers$(NSArrayFromObjects(supportedAlgos));
52
- }
53
- if (!isSecurityKey) {
54
- registrationOptions.setShouldRequireResidentKey$(residentKeyRequired);
55
- }
56
- const excludeList = [];
57
- for (const cred of excludeCredentials) {
58
- const transports = [];
59
- if (cred.transports) {
60
- for (const transport of cred.transports) {
61
- transports.push(NSStringFromString(transport));
62
- }
63
- }
64
- const credentialID = NSDataFromBuffer(cred.id);
65
- const transportsArray = NSArrayFromObjects(transports);
66
- const initializedDescriptor = ASCPublicKeyCredentialDescriptor.alloc().initWithCredentialID$transports$(credentialID, transportsArray);
67
- excludeList.push(initializedDescriptor);
68
- }
69
- if (excludeList.length > 0) {
70
- registrationOptions.setExcludedCredentials$(NSArrayFromObjects(excludeList));
71
- }
72
- }
73
- return context;
74
- },
75
- },
76
- },
77
- });
@@ -1,43 +0,0 @@
1
- export type CreateCredentialErrorCodes = "TypeError" | "AbortError" | "NotAllowedError" | "SecurityError" | "InvalidStateError";
2
- export interface CreateCredentialSuccessData {
3
- credentialId: string;
4
- clientDataJSON: string;
5
- attestationObject: string;
6
- authData: string;
7
- publicKey: string;
8
- publicKeyAlgorithm: number;
9
- transports: string[];
10
- extensions: {
11
- credProps?: {
12
- rk: boolean;
13
- };
14
- prf?: {
15
- enabled?: boolean;
16
- results: {
17
- first?: string;
18
- second?: string;
19
- };
20
- };
21
- largeBlob?: {
22
- supported?: boolean;
23
- };
24
- };
25
- }
26
- interface WebauthnCreateRequestOptions {
27
- currentOrigin: string;
28
- topFrameOrigin: string | undefined;
29
- isPublicSuffix?: (domain: string) => boolean;
30
- nativeWindowHandle: Buffer;
31
- }
32
- interface CreateCredentialSuccessResult {
33
- success: true;
34
- data: CreateCredentialSuccessData;
35
- }
36
- interface CreateCredentialErrorResult {
37
- success: false;
38
- error: CreateCredentialErrorCodes;
39
- errorObject?: Error;
40
- }
41
- export type CreateCredentialResult = CreateCredentialSuccessResult | CreateCredentialErrorResult;
42
- export declare function createCredential(publicKeyOptions: PublicKeyCredentialCreationOptions | undefined, additionalOptions: WebauthnCreateRequestOptions): Promise<CreateCredentialResult>;
43
- export {};
@@ -1,224 +0,0 @@
1
- import { bufferSourceToBuffer, bufferToBase64Url } from "../helpers/index.js";
2
- import { isRpIdAllowedForOrigin } from "../helpers/rpid.js";
3
- import { isNumber, isObject, isString } from "../helpers/validation.js";
4
- import { createCredentialInternal, } from "./internal-handler.js";
5
- function getExtensionsConfiguration(extensionsData) {
6
- if (!(extensionsData && typeof extensionsData === "object")) {
7
- return {
8
- extensions: [],
9
- };
10
- }
11
- const extensions = [];
12
- let largeBlobSupport;
13
- if (isObject(extensionsData.largeBlob)) {
14
- extensions.push("largeBlob");
15
- const largeBlobConfig = extensionsData.largeBlob;
16
- if (largeBlobConfig.support === "required") {
17
- largeBlobSupport = "required";
18
- }
19
- else if (largeBlobConfig.support === "preferred") {
20
- largeBlobSupport = "preferred";
21
- }
22
- }
23
- let prf;
24
- if (isObject(extensionsData.prf)) {
25
- const prfEval = extensionsData.prf.eval;
26
- if (prfEval) {
27
- const first = bufferSourceToBuffer(prfEval.first);
28
- const second = bufferSourceToBuffer(prfEval.second);
29
- if (first) {
30
- prf = {
31
- first: first ? first : null,
32
- second: second ? second : undefined,
33
- };
34
- }
35
- else {
36
- console.warn("[electron-webauthn] prf is enabled but prf.first is not valid, skipping PRF evaluation");
37
- }
38
- }
39
- }
40
- return {
41
- extensions,
42
- largeBlobSupport,
43
- prf,
44
- };
45
- }
46
- export async function createCredential(publicKeyOptions, additionalOptions) {
47
- if (!publicKeyOptions) {
48
- return null;
49
- }
50
- const rpInfo = publicKeyOptions.rp;
51
- if (!isObject(rpInfo)) {
52
- return { success: false, error: "TypeError" };
53
- }
54
- let rpId = rpInfo.id;
55
- if (!rpId) {
56
- try {
57
- const url = new URL(additionalOptions.currentOrigin);
58
- rpId = url.hostname;
59
- }
60
- catch { }
61
- }
62
- if (!isString(rpId)) {
63
- return { success: false, error: "TypeError" };
64
- }
65
- let timeout = publicKeyOptions.timeout;
66
- if (!isNumber(timeout) || timeout <= 0) {
67
- timeout = 10 * 60 * 1000;
68
- }
69
- else if (timeout > 60 * 60 * 1000) {
70
- timeout = 60 * 60 * 1000;
71
- }
72
- const challenge = bufferSourceToBuffer(publicKeyOptions.challenge);
73
- if (!challenge) {
74
- return { success: false, error: "TypeError" };
75
- }
76
- if (!isObject(publicKeyOptions.user)) {
77
- return { success: false, error: "TypeError" };
78
- }
79
- const userName = publicKeyOptions.user.name;
80
- const userDisplayName = publicKeyOptions.user.displayName;
81
- if (!isString(userName) || !isString(userDisplayName)) {
82
- return { success: false, error: "TypeError" };
83
- }
84
- const userID = bufferSourceToBuffer(publicKeyOptions.user.id);
85
- if (!userID) {
86
- return { success: false, error: "TypeError" };
87
- }
88
- const attestationPreference = publicKeyOptions.attestation;
89
- if (attestationPreference && !isString(attestationPreference)) {
90
- return { success: false, error: "TypeError" };
91
- }
92
- const pubKeyCredParams = publicKeyOptions.pubKeyCredParams;
93
- const supportedAlgorithmIdentifiers = [];
94
- if (pubKeyCredParams) {
95
- if (Array.isArray(pubKeyCredParams)) {
96
- for (const param of pubKeyCredParams) {
97
- if (!isObject(param))
98
- continue;
99
- if (!isNumber(param.alg))
100
- continue;
101
- supportedAlgorithmIdentifiers.push({
102
- type: "public-key",
103
- algorithm: param.alg,
104
- });
105
- }
106
- }
107
- else {
108
- return { success: false, error: "TypeError" };
109
- }
110
- }
111
- if (supportedAlgorithmIdentifiers.length === 0) {
112
- supportedAlgorithmIdentifiers.push({
113
- type: "public-key",
114
- algorithm: -7,
115
- });
116
- supportedAlgorithmIdentifiers.push({
117
- type: "public-key",
118
- algorithm: -257,
119
- });
120
- }
121
- const excludeCredentials = [];
122
- if (publicKeyOptions.excludeCredentials &&
123
- Array.isArray(publicKeyOptions.excludeCredentials)) {
124
- for (const excludeCredential of publicKeyOptions.excludeCredentials) {
125
- if (!isObject(excludeCredential))
126
- continue;
127
- if (excludeCredential.type !== "public-key")
128
- continue;
129
- const idBuffer = bufferSourceToBuffer(excludeCredential.id);
130
- if (!idBuffer)
131
- continue;
132
- excludeCredentials.push({
133
- id: idBuffer,
134
- transports: excludeCredential.transports,
135
- });
136
- }
137
- }
138
- const { extensions, largeBlobSupport, prf } = getExtensionsConfiguration(publicKeyOptions.extensions);
139
- let residentKeyRequired = false;
140
- let userVerificationPreference = "preferred";
141
- let preferredAuthenticatorAttachment = "all";
142
- if (publicKeyOptions.authenticatorSelection) {
143
- if (publicKeyOptions.authenticatorSelection.residentKey === "required") {
144
- residentKeyRequired = true;
145
- }
146
- else if (publicKeyOptions.authenticatorSelection.requireResidentKey) {
147
- residentKeyRequired = true;
148
- }
149
- const userVerifyParam = publicKeyOptions.authenticatorSelection.userVerification;
150
- if (userVerifyParam === "required") {
151
- userVerificationPreference = "required";
152
- }
153
- else if (userVerifyParam === "discouraged") {
154
- userVerificationPreference = "discouraged";
155
- }
156
- else {
157
- userVerificationPreference = "preferred";
158
- }
159
- const attachment = publicKeyOptions.authenticatorSelection.authenticatorAttachment;
160
- if (attachment === "cross-platform") {
161
- preferredAuthenticatorAttachment = "cross-platform";
162
- }
163
- else if (attachment === "platform") {
164
- preferredAuthenticatorAttachment = "platform";
165
- }
166
- }
167
- const { currentOrigin, topFrameOrigin, isPublicSuffix, nativeWindowHandle } = additionalOptions;
168
- const isRpIdAllowed = isRpIdAllowedForOrigin(currentOrigin, rpId, {
169
- isPublicSuffix,
170
- });
171
- if (!isRpIdAllowed.ok) {
172
- return { success: false, error: "NotAllowedError" };
173
- }
174
- let errorResult = null;
175
- const result = await createCredentialInternal(rpId, challenge, userName, userID, nativeWindowHandle, currentOrigin, timeout, extensions, attestationPreference, supportedAlgorithmIdentifiers, excludeCredentials, residentKeyRequired, preferredAuthenticatorAttachment, userVerificationPreference, {
176
- topFrameOrigin,
177
- largeBlobSupport,
178
- prf,
179
- }).catch((error) => {
180
- errorResult = error;
181
- if (error.message.includes("(com.apple.AuthenticationServices.AuthorizationError error 1006.)")) {
182
- return "InvalidStateError";
183
- }
184
- if (error.message.startsWith("The operation couldn’t be completed.")) {
185
- return "NotAllowedError";
186
- }
187
- return null;
188
- });
189
- if (typeof result === "string") {
190
- return { success: false, error: result, errorObject: errorResult };
191
- }
192
- const data = {
193
- credentialId: bufferToBase64Url(result.credentialId),
194
- clientDataJSON: bufferToBase64Url(result.clientDataJSON),
195
- attestationObject: bufferToBase64Url(result.attestationObject),
196
- authData: bufferToBase64Url(result.authenticatorData),
197
- publicKey: bufferToBase64Url(result.publicKey),
198
- publicKeyAlgorithm: result.publicKeyAlgorithm,
199
- transports: result.transports,
200
- extensions: {},
201
- };
202
- if (publicKeyOptions.extensions?.credProps) {
203
- data.extensions.credProps = {
204
- rk: result.isResidentKey,
205
- };
206
- }
207
- if (result.isLargeBlobSupported !== null) {
208
- data.extensions.largeBlob = {
209
- supported: result.isLargeBlobSupported,
210
- };
211
- }
212
- if (result.isPRFSupported !== null) {
213
- const prfFirst = result.prfFirst;
214
- const prfSecond = result.prfSecond;
215
- data.extensions.prf = {
216
- enabled: result.isPRFSupported,
217
- results: {
218
- first: prfFirst ? bufferToBase64Url(prfFirst) : undefined,
219
- second: prfSecond ? bufferToBase64Url(prfSecond) : undefined,
220
- },
221
- };
222
- }
223
- return { success: true, data };
224
- }
@@ -1,35 +0,0 @@
1
- import { type PRFInput } from "../helpers/prf.js";
2
- import { type PublicKeyCredentialParams } from "./authorization-controller.js";
3
- export type AuthenticatorAttachmentWithExtra = AuthenticatorAttachment | "all";
4
- export interface CreateCredentialResult {
5
- credentialId: Buffer;
6
- clientDataJSON: Buffer;
7
- attestationObject: Buffer;
8
- authenticatorData: Buffer;
9
- attachment: AuthenticatorAttachment;
10
- transports: string[];
11
- isResidentKey: boolean;
12
- publicKeyAlgorithm: number;
13
- publicKey: Buffer;
14
- isLargeBlobSupported: boolean | null;
15
- isPRFSupported: boolean | null;
16
- prfFirst: Buffer | null;
17
- prfSecond: Buffer | null;
18
- }
19
- type CredentialUserVerificationPreference = "required" | "preferred" | "discouraged";
20
- type CredentialAttestationPreference = "direct" | "enterprise" | "indirect" | "none";
21
- declare const VALID_EXTENSIONS: readonly ["largeBlob", "prf"];
22
- export type CredentialCreationExtensions = (typeof VALID_EXTENSIONS)[number];
23
- export type LargeBlobSupport = "required" | "preferred" | "unspecified";
24
- interface CreateCredentialAdditionalOptions {
25
- topFrameOrigin?: string;
26
- userDisplayName?: string;
27
- largeBlobSupport?: LargeBlobSupport;
28
- prf?: PRFInput;
29
- }
30
- export interface ExcludeCredential {
31
- id: Buffer;
32
- transports?: string[];
33
- }
34
- declare function createCredentialInternal(rpid: string, challenge: Buffer, username: string, userID: Buffer, nativeWindowHandle: Buffer, origin: string, timeout: number, enabledExtensions: CredentialCreationExtensions[], attestation: CredentialAttestationPreference, supportedAlgorithmIdentifiers: PublicKeyCredentialParams[], excludeCredentials: ExcludeCredential[], residentKeyRequired?: boolean, preferredAuthenticatorAttachment?: AuthenticatorAttachmentWithExtra, userVerification?: CredentialUserVerificationPreference, additionalOptions?: CreateCredentialAdditionalOptions): Promise<CreateCredentialResult>;
35
- export { createCredentialInternal };