electron-webauthn 0.0.17 → 1.0.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.
- package/dist/create/authorization-controller.js +10 -3
- package/dist/create/handler.d.ts +1 -0
- package/dist/create/handler.js +22 -4
- package/dist/create/internal-handler.d.ts +2 -1
- package/dist/create/internal-handler.js +71 -19
- package/dist/get/authorization-controller.js +4 -1
- package/dist/get/handler.d.ts +1 -0
- package/dist/get/handler.js +4 -6
- package/dist/get/internal-handler.d.ts +2 -2
- package/dist/get/internal-handler.js +13 -1
- package/dist/helpers/types.d.ts +1 -0
- package/dist/helpers/types.js +1 -0
- package/dist/objc/authentication-services/as-authorization-public-key-credential-parameters.d.ts +8 -0
- package/dist/objc/authentication-services/as-authorization-public-key-credential-parameters.js +6 -0
- package/dist/objc/authentication-services/as-authorization-security-key-public-key-credential-provider.d.ts +3 -1
- package/package.json +4 -3
|
@@ -4,7 +4,6 @@ import { NSArrayFromObjects } from "../objc/foundation/nsarray.js";
|
|
|
4
4
|
import { NSStringFromString } from "../objc/foundation/nsstring.js";
|
|
5
5
|
import { createASCPublicKeyCredentialDescriptor } from "../objc/authentication-services/as-authorization-c-public-key-credential-descriptor.js";
|
|
6
6
|
import { NSNumberFromInteger } from "../objc/foundation/nsinteger.js";
|
|
7
|
-
import { isNumber, isObject } from "../helpers/validation.js";
|
|
8
7
|
const createControllerState = new Map();
|
|
9
8
|
function getObjectPointerString(self) {
|
|
10
9
|
return getPointer(self).toBase64();
|
|
@@ -32,7 +31,13 @@ export const WebauthnCreateController = NobjcClass.define({
|
|
|
32
31
|
const context = NobjcClass.super(self, "_requestContextWithRequests$error$", requests, outError);
|
|
33
32
|
const selfPointer = getObjectPointerString(self);
|
|
34
33
|
if (context && createControllerState.has(selfPointer)) {
|
|
35
|
-
|
|
34
|
+
let isSecurityKey = false;
|
|
35
|
+
let registrationOptions = context.platformKeyCredentialCreationOptions();
|
|
36
|
+
if (!registrationOptions) {
|
|
37
|
+
registrationOptions =
|
|
38
|
+
context.securityKeyCredentialCreationOptions();
|
|
39
|
+
isSecurityKey = true;
|
|
40
|
+
}
|
|
36
41
|
const [clientDataHash, pubKeyCredParams, residentKeyRequired, excludeCredentials,] = createControllerState.get(selfPointer);
|
|
37
42
|
registrationOptions.setClientDataHash$(NSDataFromBuffer(clientDataHash));
|
|
38
43
|
registrationOptions.setChallenge$(null);
|
|
@@ -45,7 +50,9 @@ export const WebauthnCreateController = NobjcClass.define({
|
|
|
45
50
|
if (supportedAlgos.length > 0) {
|
|
46
51
|
registrationOptions.setSupportedAlgorithmIdentifiers$(NSArrayFromObjects(supportedAlgos));
|
|
47
52
|
}
|
|
48
|
-
|
|
53
|
+
if (!isSecurityKey) {
|
|
54
|
+
registrationOptions.setShouldRequireResidentKey$(residentKeyRequired);
|
|
55
|
+
}
|
|
49
56
|
const excludeList = [];
|
|
50
57
|
for (const cred of excludeCredentials) {
|
|
51
58
|
const transports = [];
|
package/dist/create/handler.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ interface CreateCredentialSuccessResult {
|
|
|
35
35
|
interface CreateCredentialErrorResult {
|
|
36
36
|
success: false;
|
|
37
37
|
error: "TypeError" | "AbortError" | "NotAllowedError" | "SecurityError" | "InvalidStateError";
|
|
38
|
+
errorObject?: Error;
|
|
38
39
|
}
|
|
39
40
|
export type CreateCredentialResult = CreateCredentialSuccessResult | CreateCredentialErrorResult;
|
|
40
41
|
export declare function createCredential(publicKeyOptions: PublicKeyCredentialCreationOptions | undefined, additionalOptions: WebauthnCreateRequestOptions): Promise<CreateCredentialResult>;
|
package/dist/create/handler.js
CHANGED
|
@@ -108,6 +108,16 @@ export async function createCredential(publicKeyOptions, additionalOptions) {
|
|
|
108
108
|
return { success: false, error: "TypeError" };
|
|
109
109
|
}
|
|
110
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
|
+
}
|
|
111
121
|
const excludeCredentials = [];
|
|
112
122
|
if (publicKeyOptions.excludeCredentials &&
|
|
113
123
|
Array.isArray(publicKeyOptions.excludeCredentials)) {
|
|
@@ -128,6 +138,7 @@ export async function createCredential(publicKeyOptions, additionalOptions) {
|
|
|
128
138
|
const { extensions, largeBlobSupport, prf } = getExtensionsConfiguration(publicKeyOptions.extensions);
|
|
129
139
|
let residentKeyRequired = false;
|
|
130
140
|
let userVerificationPreference = "preferred";
|
|
141
|
+
let preferredAuthenticatorAttachment = "all";
|
|
131
142
|
if (publicKeyOptions.authenticatorSelection) {
|
|
132
143
|
if (publicKeyOptions.authenticatorSelection.residentKey === "required") {
|
|
133
144
|
residentKeyRequired = true;
|
|
@@ -145,6 +156,13 @@ export async function createCredential(publicKeyOptions, additionalOptions) {
|
|
|
145
156
|
else {
|
|
146
157
|
userVerificationPreference = "preferred";
|
|
147
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
|
+
}
|
|
148
166
|
}
|
|
149
167
|
const { currentOrigin, topFrameOrigin, isPublicSuffix, nativeWindowHandle } = additionalOptions;
|
|
150
168
|
const isRpIdAllowed = isRpIdAllowedForOrigin(currentOrigin, rpId, {
|
|
@@ -153,13 +171,13 @@ export async function createCredential(publicKeyOptions, additionalOptions) {
|
|
|
153
171
|
if (!isRpIdAllowed.ok) {
|
|
154
172
|
return { success: false, error: "NotAllowedError" };
|
|
155
173
|
}
|
|
156
|
-
|
|
174
|
+
let errorResult = null;
|
|
175
|
+
const result = await createCredentialInternal(rpId, challenge, userName, userID, nativeWindowHandle, currentOrigin, timeout, extensions, attestationPreference, supportedAlgorithmIdentifiers, excludeCredentials, residentKeyRequired, preferredAuthenticatorAttachment, userVerificationPreference, {
|
|
157
176
|
topFrameOrigin,
|
|
158
177
|
largeBlobSupport,
|
|
159
178
|
prf,
|
|
160
179
|
}).catch((error) => {
|
|
161
|
-
|
|
162
|
-
console.log("error.message", error.message);
|
|
180
|
+
errorResult = error;
|
|
163
181
|
if (error.message.includes("(com.apple.AuthenticationServices.AuthorizationError error 1006.)")) {
|
|
164
182
|
return "InvalidStateError";
|
|
165
183
|
}
|
|
@@ -169,7 +187,7 @@ export async function createCredential(publicKeyOptions, additionalOptions) {
|
|
|
169
187
|
return null;
|
|
170
188
|
});
|
|
171
189
|
if (typeof result === "string") {
|
|
172
|
-
return { success: false, error: result };
|
|
190
|
+
return { success: false, error: result, errorObject: errorResult };
|
|
173
191
|
}
|
|
174
192
|
const data = {
|
|
175
193
|
credentialId: bufferToBase64Url(result.credentialId),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type PRFInput } from "../helpers/prf.js";
|
|
2
2
|
import { type PublicKeyCredentialParams } from "./authorization-controller.js";
|
|
3
|
+
export type AuthenticatorAttachmentWithExtra = AuthenticatorAttachment | "all";
|
|
3
4
|
export interface CreateCredentialResult {
|
|
4
5
|
credentialId: Buffer;
|
|
5
6
|
clientDataJSON: Buffer;
|
|
@@ -30,5 +31,5 @@ export interface ExcludeCredential {
|
|
|
30
31
|
id: Buffer;
|
|
31
32
|
transports?: string[];
|
|
32
33
|
}
|
|
33
|
-
declare function createCredentialInternal(rpid: string, challenge: Buffer, username: string, userID: Buffer, nativeWindowHandle: Buffer, origin: string, enabledExtensions: CredentialCreationExtensions[], attestation: CredentialAttestationPreference, supportedAlgorithmIdentifiers: PublicKeyCredentialParams[], excludeCredentials: ExcludeCredential[], residentKeyRequired?: boolean, userVerification?: CredentialUserVerificationPreference, additionalOptions?: CreateCredentialAdditionalOptions): Promise<CreateCredentialResult>;
|
|
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>;
|
|
34
35
|
export { createCredentialInternal };
|
|
@@ -17,16 +17,11 @@ import { NSStringFromString } from "../objc/foundation/nsstring.js";
|
|
|
17
17
|
import { removeControllerState, setControllerState, WebauthnCreateController, } from "./authorization-controller.js";
|
|
18
18
|
import { parseAttestationObject } from "@oslojs/webauthn";
|
|
19
19
|
import { ASAuthorizationPublicKeyCredentialAttachment } from "../objc/authentication-services/enums/as-authorization-public-key-credential-attachment.js";
|
|
20
|
+
import { createSecurityKeyPublicKeyCredentialProvider } from "../objc/authentication-services/as-authorization-security-key-public-key-credential-provider.js";
|
|
21
|
+
import { createASAuthorizationPublicKeyCredentialParameters, } from "../objc/authentication-services/as-authorization-public-key-credential-parameters.js";
|
|
20
22
|
const VALID_EXTENSIONS = ["largeBlob", "prf"];
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
const NS_rpID = NSStringFromString(rpid);
|
|
24
|
-
const NS_challenge = NSDataFromBuffer(challenge);
|
|
25
|
-
const NS_username = NSStringFromString(username);
|
|
26
|
-
const NS_userID = NSDataFromBuffer(userID);
|
|
27
|
-
const platformProvider = createPlatformPublicKeyCredentialProvider(NS_rpID);
|
|
28
|
-
const platformKeyRequest = platformProvider.createCredentialRegistrationRequestWithChallenge$name$userID$(NS_challenge, NS_username, NS_userID);
|
|
29
|
-
if (enabledExtensions.includes("largeBlob")) {
|
|
23
|
+
function setupPublicKeyCredentialRegistrationRequest(type, keyRequest, attestation, enabledExtensions, userVerification, pubKeyCredParams, additionalOptions) {
|
|
24
|
+
if (type === "platform" && enabledExtensions.includes("largeBlob")) {
|
|
30
25
|
let supportMode;
|
|
31
26
|
const largeBlobSupport = additionalOptions.largeBlobSupport;
|
|
32
27
|
if (largeBlobSupport === "required") {
|
|
@@ -42,11 +37,25 @@ function createCredentialInternal(rpid, challenge, username, userID, nativeWindo
|
|
|
42
37
|
}
|
|
43
38
|
if (supportMode) {
|
|
44
39
|
const largeBlobInput = createASAuthorizationPublicKeyCredentialLargeBlobRegistrationInput(supportMode);
|
|
45
|
-
|
|
40
|
+
keyRequest.setLargeBlob$(largeBlobInput);
|
|
46
41
|
}
|
|
47
42
|
}
|
|
48
43
|
let attestationPreference = ASAuthorizationPublicKeyCredentialAttestationKind.None;
|
|
49
|
-
|
|
44
|
+
if (type === "security-key") {
|
|
45
|
+
if (attestation === "direct") {
|
|
46
|
+
attestationPreference =
|
|
47
|
+
ASAuthorizationPublicKeyCredentialAttestationKind.Direct;
|
|
48
|
+
}
|
|
49
|
+
else if (attestation === "enterprise") {
|
|
50
|
+
attestationPreference =
|
|
51
|
+
ASAuthorizationPublicKeyCredentialAttestationKind.Enterprise;
|
|
52
|
+
}
|
|
53
|
+
else if (attestation === "indirect") {
|
|
54
|
+
attestationPreference =
|
|
55
|
+
ASAuthorizationPublicKeyCredentialAttestationKind.Indirect;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
keyRequest.setAttestationPreference$(NSStringFromString(attestationPreference));
|
|
50
59
|
let userVerificationPreference = ASAuthorizationPublicKeyCredentialUserVerificationPreference.Preferred;
|
|
51
60
|
if (userVerification === "required") {
|
|
52
61
|
userVerificationPreference =
|
|
@@ -56,28 +65,67 @@ function createCredentialInternal(rpid, challenge, username, userID, nativeWindo
|
|
|
56
65
|
userVerificationPreference =
|
|
57
66
|
ASAuthorizationPublicKeyCredentialUserVerificationPreference.Discouraged;
|
|
58
67
|
}
|
|
59
|
-
|
|
60
|
-
if (additionalOptions.userDisplayName) {
|
|
68
|
+
keyRequest.setUserVerificationPreference$(NSStringFromString(userVerificationPreference));
|
|
69
|
+
if (type === "platform" && additionalOptions.userDisplayName) {
|
|
61
70
|
const userDisplayName = NSStringFromString(additionalOptions.userDisplayName);
|
|
62
|
-
|
|
71
|
+
keyRequest.setDisplayName$(userDisplayName);
|
|
63
72
|
}
|
|
64
|
-
if (
|
|
73
|
+
if (type === "security-key") {
|
|
74
|
+
const credentialParameters = [];
|
|
75
|
+
for (const param of pubKeyCredParams) {
|
|
76
|
+
if (param.type === "public-key") {
|
|
77
|
+
credentialParameters.push(createASAuthorizationPublicKeyCredentialParameters(param.algorithm));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const nsCredentialParameters = NSArrayFromObjects(credentialParameters);
|
|
81
|
+
keyRequest.setCredentialParameters$(nsCredentialParameters);
|
|
82
|
+
}
|
|
83
|
+
if (type === "platform" && enabledExtensions.includes("prf")) {
|
|
65
84
|
if (additionalOptions.prf) {
|
|
66
85
|
const inputValues = createPRFInput(additionalOptions.prf);
|
|
67
86
|
const prfInput = createASAuthorizationPublicKeyCredentialPRFRegistrationInput(inputValues);
|
|
68
|
-
|
|
87
|
+
keyRequest.setPrf$(prfInput);
|
|
69
88
|
}
|
|
70
89
|
else {
|
|
71
|
-
|
|
90
|
+
keyRequest.setPrf$(ASAuthorizationPublicKeyCredentialPRFRegistrationInput.checkForSupport());
|
|
72
91
|
}
|
|
73
92
|
}
|
|
74
|
-
|
|
93
|
+
}
|
|
94
|
+
function createCredentialInternal(rpid, challenge, username, userID, nativeWindowHandle, origin, timeout, enabledExtensions, attestation = "none", supportedAlgorithmIdentifiers = [], excludeCredentials, residentKeyRequired = false, preferredAuthenticatorAttachment = "all", userVerification = "preferred", additionalOptions = {}) {
|
|
95
|
+
const { promise, resolve, reject } = PromiseWithResolvers();
|
|
96
|
+
const NS_rpID = NSStringFromString(rpid);
|
|
97
|
+
const NS_challenge = NSDataFromBuffer(challenge);
|
|
98
|
+
const NS_username = NSStringFromString(username);
|
|
99
|
+
const NS_userID = NSDataFromBuffer(userID);
|
|
100
|
+
const requestArrayInput = [];
|
|
101
|
+
if (preferredAuthenticatorAttachment === "all" ||
|
|
102
|
+
preferredAuthenticatorAttachment === "platform") {
|
|
103
|
+
const platformProvider = createPlatformPublicKeyCredentialProvider(NS_rpID);
|
|
104
|
+
const platformKeyRequest = platformProvider.createCredentialRegistrationRequestWithChallenge$name$userID$(NS_challenge, NS_username, NS_userID);
|
|
105
|
+
setupPublicKeyCredentialRegistrationRequest("platform", platformKeyRequest, attestation, enabledExtensions, userVerification, supportedAlgorithmIdentifiers, additionalOptions);
|
|
106
|
+
requestArrayInput.push(platformKeyRequest);
|
|
107
|
+
}
|
|
108
|
+
if (preferredAuthenticatorAttachment === "all" ||
|
|
109
|
+
preferredAuthenticatorAttachment === "cross-platform") {
|
|
110
|
+
const securityKeyProvider = createSecurityKeyPublicKeyCredentialProvider(NS_rpID);
|
|
111
|
+
const securityKeyRequest = securityKeyProvider.createCredentialRegistrationRequestWithChallenge$displayName$name$userID$(NS_challenge, NSStringFromString(additionalOptions.userDisplayName || username), NS_username, NS_userID);
|
|
112
|
+
setupPublicKeyCredentialRegistrationRequest("security-key", securityKeyRequest, attestation, enabledExtensions, userVerification, supportedAlgorithmIdentifiers, additionalOptions);
|
|
113
|
+
requestArrayInput.push(securityKeyRequest);
|
|
114
|
+
}
|
|
115
|
+
const requestsArray = NSArrayFromObjects(requestArrayInput);
|
|
75
116
|
const authController = WebauthnCreateController.alloc().initWithAuthorizationRequests$(requestsArray);
|
|
76
117
|
const clientData = generateWebauthnClientData("webauthn.create", origin, challenge, additionalOptions.topFrameOrigin);
|
|
77
118
|
const { clientDataHash, clientDataBuffer } = generateClientDataInfo(clientData);
|
|
78
119
|
setControllerState(authController, clientDataHash, supportedAlgorithmIdentifiers, residentKeyRequired, excludeCredentials);
|
|
120
|
+
let isFinished = false;
|
|
121
|
+
let timeoutHandlerId = null;
|
|
79
122
|
const finished = (_success) => {
|
|
123
|
+
isFinished = true;
|
|
80
124
|
removeControllerState(authController);
|
|
125
|
+
if (timeoutHandlerId) {
|
|
126
|
+
clearTimeout(timeoutHandlerId);
|
|
127
|
+
timeoutHandlerId = null;
|
|
128
|
+
}
|
|
81
129
|
};
|
|
82
130
|
const delegate = createAuthorizationControllerDelegate({
|
|
83
131
|
didCompleteWithAuthorization: (_, authorization) => {
|
|
@@ -140,7 +188,6 @@ function createCredentialInternal(rpid, challenge, username, userID, nativeWindo
|
|
|
140
188
|
didCompleteWithError: (_, error) => {
|
|
141
189
|
const parsedError = error;
|
|
142
190
|
const errorMessage = parsedError.localizedDescription().UTF8String();
|
|
143
|
-
console.error("Authorization failed:", errorMessage);
|
|
144
191
|
reject(new Error(errorMessage));
|
|
145
192
|
finished(false);
|
|
146
193
|
},
|
|
@@ -149,6 +196,11 @@ function createCredentialInternal(rpid, challenge, username, userID, nativeWindo
|
|
|
149
196
|
const presentationContextProvider = createPresentationContextProviderFromNativeWindowHandle(nativeWindowHandle);
|
|
150
197
|
authController.setPresentationContextProvider$(presentationContextProvider);
|
|
151
198
|
authController.performRequests();
|
|
199
|
+
timeoutHandlerId = setTimeout(() => {
|
|
200
|
+
if (isFinished)
|
|
201
|
+
return;
|
|
202
|
+
authController.cancel();
|
|
203
|
+
}, timeout);
|
|
152
204
|
return promise;
|
|
153
205
|
}
|
|
154
206
|
export { createCredentialInternal };
|
|
@@ -22,7 +22,10 @@ export const WebauthnGetController = NobjcClass.define({
|
|
|
22
22
|
const context = NobjcClass.super(self, "_requestContextWithRequests$error$", requests, outError);
|
|
23
23
|
const selfPointer = getObjectPointerString(self);
|
|
24
24
|
if (getControllerState.has(selfPointer)) {
|
|
25
|
-
|
|
25
|
+
let assertionOptions = context.platformKeyCredentialAssertionOptions();
|
|
26
|
+
if (!assertionOptions) {
|
|
27
|
+
assertionOptions = context.securityKeyCredentialAssertionOptions();
|
|
28
|
+
}
|
|
26
29
|
const clientDataHash = getControllerState.get(selfPointer);
|
|
27
30
|
assertionOptions.setClientDataHash$(NSDataFromBuffer(clientDataHash));
|
|
28
31
|
context.setPlatformKeyCredentialAssertionOptions$(assertionOptions.copyWithZone$(null));
|
package/dist/get/handler.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ interface GetCredentialSuccessResult {
|
|
|
30
30
|
interface GetCredentialErrorResult {
|
|
31
31
|
success: false;
|
|
32
32
|
error: "TypeError" | "AbortError" | "NotAllowedError" | "SecurityError";
|
|
33
|
+
errorObject?: Error;
|
|
33
34
|
}
|
|
34
35
|
export type GetCredentialResult = GetCredentialSuccessResult | GetCredentialErrorResult;
|
|
35
36
|
export declare function getCredential(publicKeyOptions: PublicKeyCredentialRequestOptions | undefined, additionalOptions: WebauthnGetRequestOptions): Promise<GetCredentialResult>;
|
package/dist/get/handler.js
CHANGED
|
@@ -95,23 +95,21 @@ export async function getCredential(publicKeyOptions, additionalOptions) {
|
|
|
95
95
|
if (!isRpIdAllowed.ok) {
|
|
96
96
|
return { success: false, error: "NotAllowedError" };
|
|
97
97
|
}
|
|
98
|
-
|
|
98
|
+
let errorResult = null;
|
|
99
|
+
const result = await getCredentialInternal(rpId, challenge, nativeWindowHandle, currentOrigin, timeout, enabledExtensions, allowedCredentialsArray, userVerification, {
|
|
99
100
|
topFrameOrigin,
|
|
100
101
|
largeBlobDataToWrite: largeBlobWriteBuffer,
|
|
101
102
|
prf,
|
|
102
103
|
prfByCredential,
|
|
103
104
|
}).catch((error) => {
|
|
104
|
-
|
|
105
|
+
errorResult = error;
|
|
105
106
|
if (error.message.startsWith("The operation couldn’t be completed.")) {
|
|
106
107
|
return "NotAllowedError";
|
|
107
108
|
}
|
|
108
109
|
return "NotAllowedError";
|
|
109
110
|
});
|
|
110
111
|
if (typeof result === "string") {
|
|
111
|
-
|
|
112
|
-
return { success: false, error: "NotAllowedError" };
|
|
113
|
-
}
|
|
114
|
-
return { success: false, error: "NotAllowedError" };
|
|
112
|
+
return { success: false, error: result, errorObject: errorResult };
|
|
115
113
|
}
|
|
116
114
|
const data = {
|
|
117
115
|
credentialId: bufferToBase64Url(result.id),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type PRFInput } from "../helpers/prf.js";
|
|
2
|
-
type AuthenticatorAttachment
|
|
2
|
+
import type { AuthenticatorAttachment } from "../helpers/types.js";
|
|
3
3
|
export type UserVerificationPreference = "preferred" | "required" | "discouraged";
|
|
4
4
|
declare const VALID_EXTENSIONS: readonly ["largeBlobRead", "largeBlobWrite", "prf"];
|
|
5
5
|
export type CredentialAssertionExtensions = (typeof VALID_EXTENSIONS)[number];
|
|
@@ -20,5 +20,5 @@ export interface GetCredentialAdditionalOptions {
|
|
|
20
20
|
prfByCredential?: Record<string, PRFInput>;
|
|
21
21
|
topFrameOrigin?: string;
|
|
22
22
|
}
|
|
23
|
-
declare function getCredentialInternal(rpid: string, challenge: Buffer, nativeWindowHandle: Buffer, origin: string, enabledExtensions: CredentialAssertionExtensions[], allowedCredentialIds: Buffer[], userVerificationPreference?: UserVerificationPreference, additionalOptions?: GetCredentialAdditionalOptions): Promise<GetCredentialResult>;
|
|
23
|
+
declare function getCredentialInternal(rpid: string, challenge: Buffer, nativeWindowHandle: Buffer, origin: string, timeout: number, enabledExtensions: CredentialAssertionExtensions[], allowedCredentialIds: Buffer[], userVerificationPreference?: UserVerificationPreference, additionalOptions?: GetCredentialAdditionalOptions): Promise<GetCredentialResult>;
|
|
24
24
|
export { getCredentialInternal };
|
|
@@ -76,7 +76,7 @@ function setupPublicKeyCredentialRequest(type, keyRequest, userVerificationPrefe
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
-
function getCredentialInternal(rpid, challenge, nativeWindowHandle, origin, enabledExtensions = [], allowedCredentialIds, userVerificationPreference, additionalOptions = {}) {
|
|
79
|
+
function getCredentialInternal(rpid, challenge, nativeWindowHandle, origin, timeout, enabledExtensions = [], allowedCredentialIds, userVerificationPreference, additionalOptions = {}) {
|
|
80
80
|
const { promise, resolve, reject } = PromiseWithResolvers();
|
|
81
81
|
const NS_rpID = NSStringFromString(rpid);
|
|
82
82
|
const NS_challenge = NSDataFromBuffer(challenge);
|
|
@@ -94,8 +94,15 @@ function getCredentialInternal(rpid, challenge, nativeWindowHandle, origin, enab
|
|
|
94
94
|
const clientData = generateWebauthnClientData("webauthn.get", origin, challenge, additionalOptions.topFrameOrigin);
|
|
95
95
|
const { clientDataHash, clientDataBuffer } = generateClientDataInfo(clientData);
|
|
96
96
|
setClientDataHash(authController, clientDataHash);
|
|
97
|
+
let isFinished = false;
|
|
98
|
+
let timeoutHandlerId = null;
|
|
97
99
|
const finished = (_success) => {
|
|
100
|
+
isFinished = true;
|
|
98
101
|
removeClientDataHash(authController);
|
|
102
|
+
if (timeoutHandlerId) {
|
|
103
|
+
clearTimeout(timeoutHandlerId);
|
|
104
|
+
timeoutHandlerId = null;
|
|
105
|
+
}
|
|
99
106
|
};
|
|
100
107
|
if (allowedCredentialIds.length > 0) {
|
|
101
108
|
const allowedCredentials = NSArrayFromObjects(allowedCredentialIds.map((id) => createPlatformPublicKeyCredentialDescriptor(NSDataFromBuffer(id))));
|
|
@@ -152,6 +159,11 @@ function getCredentialInternal(rpid, challenge, nativeWindowHandle, origin, enab
|
|
|
152
159
|
const presentationContextProvider = createPresentationContextProviderFromNativeWindowHandle(nativeWindowHandle);
|
|
153
160
|
authController.setPresentationContextProvider$(presentationContextProvider);
|
|
154
161
|
authController.performRequests();
|
|
162
|
+
timeoutHandlerId = setTimeout(() => {
|
|
163
|
+
if (isFinished)
|
|
164
|
+
return;
|
|
165
|
+
authController.cancel();
|
|
166
|
+
}, timeout);
|
|
155
167
|
return promise;
|
|
156
168
|
}
|
|
157
169
|
export { getCredentialInternal };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type AuthenticatorAttachment = "platform" | "cross-platform";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/objc/authentication-services/as-authorization-public-key-credential-parameters.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { NobjcObject } from "objc-js";
|
|
2
|
+
declare class _ASAuthorizationPublicKeyCredentialParameters extends NobjcObject {
|
|
3
|
+
initWithAlgorithm$(algorithm: number): _ASAuthorizationPublicKeyCredentialParameters;
|
|
4
|
+
algorithm(): number;
|
|
5
|
+
}
|
|
6
|
+
export declare const ASAuthorizationPublicKeyCredentialParameters: typeof _ASAuthorizationPublicKeyCredentialParameters;
|
|
7
|
+
export type { _ASAuthorizationPublicKeyCredentialParameters };
|
|
8
|
+
export declare function createASAuthorizationPublicKeyCredentialParameters(algorithm: number): _ASAuthorizationPublicKeyCredentialParameters;
|
package/dist/objc/authentication-services/as-authorization-public-key-credential-parameters.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { AuthenticationServices } from "./index.js";
|
|
2
|
+
export const ASAuthorizationPublicKeyCredentialParameters = AuthenticationServices.ASAuthorizationPublicKeyCredentialParameters;
|
|
3
|
+
export function createASAuthorizationPublicKeyCredentialParameters(algorithm) {
|
|
4
|
+
const instance = ASAuthorizationPublicKeyCredentialParameters.alloc();
|
|
5
|
+
return instance.initWithAlgorithm$(algorithm);
|
|
6
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { _NSData } from "../foundation/nsdata.js";
|
|
2
|
+
import type { _NSString } from "../foundation/nsstring.js";
|
|
1
3
|
import type { NobjcObject } from "objc-js";
|
|
2
4
|
declare class _ASAuthorizationSecurityKeyPublicKeyCredentialProvider extends NobjcObject {
|
|
3
5
|
initWithRelyingPartyIdentifier$(relyingPartyIdentifier: NobjcObject): _ASAuthorizationSecurityKeyPublicKeyCredentialProvider;
|
|
4
|
-
createCredentialRegistrationRequestWithChallenge$name$userID$(challenge:
|
|
6
|
+
createCredentialRegistrationRequestWithChallenge$displayName$name$userID$(challenge: _NSData, displayName: _NSString, name: _NSString, userID: _NSData): NobjcObject;
|
|
5
7
|
createCredentialAssertionRequestWithChallenge$(challenge: NobjcObject): NobjcObject;
|
|
6
8
|
}
|
|
7
9
|
export declare const ASAuthorizationSecurityKeyPublicKeyCredentialProvider: typeof _ASAuthorizationSecurityKeyPublicKeyCredentialProvider;
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "electron-webauthn",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"repository": "https://github.com/iamEvanYT/electron-webauthn.git",
|
|
5
|
+
"homepage": "https://github.com/iamEvanYT/electron-webauthn#readme",
|
|
5
6
|
"description": "Add support for WebAuthn for Electron.",
|
|
6
7
|
"main": "dist/index.js",
|
|
7
8
|
"module": "dist/index.js",
|
|
@@ -18,7 +19,7 @@
|
|
|
18
19
|
],
|
|
19
20
|
"type": "module",
|
|
20
21
|
"scripts": {
|
|
21
|
-
"build": "tsc && rm -rf dist/test",
|
|
22
|
+
"build": "rm -rf dist && tsc && rm -rf dist/test",
|
|
22
23
|
"test": "bun run src/test/index.ts"
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
},
|
|
30
31
|
"dependencies": {
|
|
31
32
|
"@oslojs/webauthn": "^1.0.0",
|
|
32
|
-
"objc-js": "^0.0
|
|
33
|
+
"objc-js": "^1.0.0"
|
|
33
34
|
},
|
|
34
35
|
"trustedDependencies": [
|
|
35
36
|
"objc-js"
|