electron-webauthn 0.0.10 → 0.0.11
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/LICENSE +21 -0
- package/README.md +247 -6
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/test/example.d.ts +2 -0
- package/dist/test/example.d.ts.map +1 -0
- package/dist/test/example.js +24 -0
- package/dist/test/example.js.map +1 -0
- package/dist/test/index.d.ts +2 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/index.js +9 -0
- package/dist/test/index.js.map +1 -0
- package/dist/test/window.d.ts +5 -0
- package/dist/test/window.d.ts.map +1 -0
- package/dist/test/window.js +58 -0
- package/dist/test/window.js.map +1 -0
- package/package.json +1 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 iamEvan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,15 +1,256 @@
|
|
|
1
|
-
# electron-webauthn
|
|
1
|
+
# electron-webauthn
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Add native WebAuthn/FIDO2 support to Electron using macOS AuthenticationServices framework.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`electron-webauthn` is a TypeScript library that bridges Electron with the native macOS AuthenticationServices framework, enabling WebAuthn/FIDO2 authentication directly through native platform authenticators (Touch ID, Face ID, hardware security keys, etc.).
|
|
8
|
+
|
|
9
|
+
This package provides JavaScript bindings to Apple's AuthenticationServices framework, allowing you to perform WebAuthn assertions (authentication/signing with existing credentials) in your Electron applications.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- 🔐 Native WebAuthn support for Electron on macOS
|
|
14
|
+
- 🎯 Support for platform authenticators (Touch ID, Face ID)
|
|
15
|
+
- 🔑 Support for cross-platform authenticators (external security keys)
|
|
16
|
+
- 📦 TypeScript first with complete type definitions
|
|
17
|
+
- 🎨 Seamless integration with Electron's native window system
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
4
20
|
|
|
5
21
|
```bash
|
|
6
|
-
|
|
22
|
+
npm install electron-webauthn
|
|
23
|
+
# or
|
|
24
|
+
bun add electron-webauthn
|
|
25
|
+
# or
|
|
26
|
+
yarn add electron-webauthn
|
|
7
27
|
```
|
|
8
28
|
|
|
9
|
-
|
|
29
|
+
### Requirements
|
|
30
|
+
|
|
31
|
+
- Electron 28+
|
|
32
|
+
- macOS 12.0+
|
|
33
|
+
- TypeScript 5+ (peer dependency)
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { getCredential } from "electron-webauthn";
|
|
39
|
+
import { getPointer } from "objc-js";
|
|
40
|
+
|
|
41
|
+
// In your Electron main process or preload script
|
|
42
|
+
async function authenticate() {
|
|
43
|
+
// Get the native window handle from your BrowserWindow
|
|
44
|
+
const nativeWindowHandle = getPointer(
|
|
45
|
+
yourElectronWindow.getNativeWindowHandle()
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
// Call getCredential to prompt the user for authentication
|
|
49
|
+
const result = await getCredential(
|
|
50
|
+
"example.com", // Relying Party ID
|
|
51
|
+
Buffer.from("your-challenge"), // Challenge from server
|
|
52
|
+
nativeWindowHandle, // Native window for UI presentation
|
|
53
|
+
[] // Optional: allowed credential IDs
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
console.log(result);
|
|
57
|
+
// Result contains:
|
|
58
|
+
// - id: Credential ID (Buffer)
|
|
59
|
+
// - authenticatorAttachment: 'platform' | 'cross-platform'
|
|
60
|
+
// - clientDataJSON: Raw client data (Buffer)
|
|
61
|
+
// - authenticatorData: Authenticator data (Buffer)
|
|
62
|
+
// - signature: Assertion signature (Buffer)
|
|
63
|
+
// - userHandle: User handle (Buffer)
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## API Reference
|
|
68
|
+
|
|
69
|
+
### `getCredential(rpid, challenge, nativeWindowHandle, allowedCredentialIds)`
|
|
70
|
+
|
|
71
|
+
Performs a WebAuthn assertion (authentication) using available platform and cross-platform authenticators.
|
|
72
|
+
|
|
73
|
+
#### Parameters
|
|
74
|
+
|
|
75
|
+
- **`rpid: string`** - The Relying Party ID (typically your domain)
|
|
76
|
+
- **`challenge: Buffer`** - The challenge from your server (32+ bytes recommended)
|
|
77
|
+
- **`nativeWindowHandle: Buffer`** - The native window handle from Electron
|
|
78
|
+
- **`allowedCredentialIds: Buffer[]`** - Optional array of credential IDs the user can use (empty = all registered credentials)
|
|
79
|
+
|
|
80
|
+
#### Returns
|
|
81
|
+
|
|
82
|
+
`Promise<GetCredentialResult>` - Resolves with the assertion result
|
|
83
|
+
|
|
84
|
+
#### Result Type
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
interface GetCredentialResult {
|
|
88
|
+
id: Buffer; // Credential ID
|
|
89
|
+
authenticatorAttachment: "platform" | "cross-platform"; // Type of authenticator used
|
|
90
|
+
clientDataJSON: Buffer; // Raw client data JSON (encoded as UTF-8 bytes)
|
|
91
|
+
authenticatorData: Buffer; // Authenticator data from the device
|
|
92
|
+
signature: Buffer; // Digital signature from the authenticator
|
|
93
|
+
userHandle: Buffer; // User handle from the credential
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Architecture
|
|
98
|
+
|
|
99
|
+
### Package Structure
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
src/
|
|
103
|
+
├── index.ts # Main export - getCredential function
|
|
104
|
+
├── helpers.ts # Utility functions
|
|
105
|
+
├── objc/
|
|
106
|
+
│ ├── authentication-services/ # AuthenticationServices framework bindings
|
|
107
|
+
│ │ ├── as-authorization-*.ts # Authorization request/response objects
|
|
108
|
+
│ │ ├── enums/ # Enumeration values
|
|
109
|
+
│ │ └── index.ts # Exports
|
|
110
|
+
│ └── foundation/ # Foundation framework bindings
|
|
111
|
+
│ ├── nsdata.ts # NSData (binary data) bindings
|
|
112
|
+
│ ├── nsstring.ts # NSString bindings
|
|
113
|
+
│ ├── nsarray.ts # NSArray bindings
|
|
114
|
+
│ ├── nserror.ts # NSError bindings
|
|
115
|
+
│ ├── nsview.ts # NSView bindings
|
|
116
|
+
│ ├── nswindow.ts # NSWindow bindings
|
|
117
|
+
│ └── index.ts # Exports
|
|
118
|
+
└── test/ # Test utilities
|
|
119
|
+
├── index.ts # Test script
|
|
120
|
+
├── window.ts # Test window helpers
|
|
121
|
+
└── example.ts # Example usage
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Dependencies
|
|
125
|
+
|
|
126
|
+
- **objc-js** - Native Objective-C bindings for JavaScript
|
|
127
|
+
- **TypeScript** - For type checking and compilation
|
|
128
|
+
|
|
129
|
+
## How It Works
|
|
130
|
+
|
|
131
|
+
1. **Request Creation**: The library creates a `ASAuthorizationPlatformPublicKeyCredentialProvider` with your RP ID
|
|
132
|
+
2. **Request Configuration**: Sets up the challenge and optional allowed credentials list
|
|
133
|
+
3. **Controller Setup**: Creates an `ASAuthorizationController` to manage the authentication flow
|
|
134
|
+
4. **Delegation**: Registers delegates to handle success/error responses from the system
|
|
135
|
+
5. **Presentation**: Shows the native authentication UI in your window
|
|
136
|
+
6. **Result Processing**: Converts Objective-C objects to JavaScript Buffers and returns the assertion data
|
|
137
|
+
|
|
138
|
+
## Usage Examples
|
|
139
|
+
|
|
140
|
+
### Basic Authentication
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
import { getCredential } from "electron-webauthn";
|
|
144
|
+
import { getPointer } from "objc-js";
|
|
145
|
+
import { app, BrowserWindow } from "electron";
|
|
146
|
+
|
|
147
|
+
let mainWindow: BrowserWindow;
|
|
148
|
+
|
|
149
|
+
app.on("ready", () => {
|
|
150
|
+
mainWindow = new BrowserWindow({
|
|
151
|
+
webPreferences: { preload: "./preload.js" },
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// In your preload script or main process
|
|
156
|
+
export async function authenticateUser(challenge: Buffer) {
|
|
157
|
+
const nativeHandle = getPointer(mainWindow.getNativeWindowHandle());
|
|
158
|
+
return getCredential("myapp.com", challenge, nativeHandle, []);
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Restricting to Specific Credentials
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// Only allow specific registered credentials
|
|
166
|
+
const result = await getCredential(
|
|
167
|
+
"myapp.com",
|
|
168
|
+
challenge,
|
|
169
|
+
nativeWindowHandle,
|
|
170
|
+
[credentialId1, credentialId2] // User can only use these credentials
|
|
171
|
+
);
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Server-Side Verification
|
|
175
|
+
|
|
176
|
+
After getting the assertion result, verify it on your server:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
// Server-side (Node.js, Python, etc.)
|
|
180
|
+
// 1. Verify the signature using the public key from the credential registration
|
|
181
|
+
// 2. Check that the challenge matches what you sent
|
|
182
|
+
// 3. Verify the authenticator data flags
|
|
183
|
+
// 4. Check the user handle matches the authenticated user
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Error Handling
|
|
187
|
+
|
|
188
|
+
The `getCredential` promise will reject if:
|
|
189
|
+
|
|
190
|
+
- The user cancels the authentication prompt
|
|
191
|
+
- No valid credentials are available
|
|
192
|
+
- The authenticator fails
|
|
193
|
+
- The native window is invalid
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
try {
|
|
197
|
+
const result = await getCredential(
|
|
198
|
+
"example.com",
|
|
199
|
+
challenge,
|
|
200
|
+
nativeWindowHandle,
|
|
201
|
+
[]
|
|
202
|
+
);
|
|
203
|
+
} catch (error) {
|
|
204
|
+
console.error("Authentication failed:", error.message);
|
|
205
|
+
// Handle error appropriately
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Platform Support
|
|
210
|
+
|
|
211
|
+
| Platform | Support |
|
|
212
|
+
| --------- | ---------------- |
|
|
213
|
+
| macOS 12+ | ✅ Full support |
|
|
214
|
+
| Windows | ❌ Not supported |
|
|
215
|
+
| Linux | ❌ Not supported |
|
|
216
|
+
| iOS | ❌ Not supported |
|
|
217
|
+
|
|
218
|
+
## WebAuthn Spec Compliance
|
|
219
|
+
|
|
220
|
+
This library implements the WebAuthn Level 2 specification for the assertion (authentication) operation:
|
|
221
|
+
|
|
222
|
+
- ✅ Public Key Credential (assertions)
|
|
223
|
+
- ✅ Platform authenticators (built-in)
|
|
224
|
+
- ✅ Cross-platform authenticators (external)
|
|
225
|
+
- ❌ Credential registration (create)
|
|
226
|
+
- ℹ️ See [WebAuthn Specification](https://www.w3.org/TR/webauthn-2/)
|
|
227
|
+
|
|
228
|
+
## Development
|
|
229
|
+
|
|
230
|
+
### Building
|
|
10
231
|
|
|
11
232
|
```bash
|
|
12
|
-
bun run
|
|
233
|
+
bun run build
|
|
13
234
|
```
|
|
14
235
|
|
|
15
|
-
This
|
|
236
|
+
This compiles TypeScript to JavaScript in the `dist/` directory.
|
|
237
|
+
|
|
238
|
+
## Contributing
|
|
239
|
+
|
|
240
|
+
Contributions are welcome! Please ensure:
|
|
241
|
+
|
|
242
|
+
1. Code is properly typed with TypeScript
|
|
243
|
+
2. New features include appropriate documentation
|
|
244
|
+
3. Tests pass with `bun run test`
|
|
245
|
+
4. Code builds successfully with `bun run build`
|
|
246
|
+
|
|
247
|
+
## License
|
|
248
|
+
|
|
249
|
+
See [LICENSE](./LICENSE) file for details.
|
|
250
|
+
|
|
251
|
+
## Related Resources
|
|
252
|
+
|
|
253
|
+
- [WebAuthn Specification](https://www.w3.org/TR/webauthn-2/)
|
|
254
|
+
- [Apple AuthenticationServices Documentation](https://developer.apple.com/documentation/authenticationservices)
|
|
255
|
+
- [Electron Documentation](https://www.electronjs.org/docs)
|
|
256
|
+
- [objc-js Library](https://github.com/iamEvanYT/objc-js)
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export interface GetCredentialResult {
|
|
|
6
6
|
authenticatorData: Buffer;
|
|
7
7
|
signature: Buffer;
|
|
8
8
|
userHandle: Buffer;
|
|
9
|
+
prf: [Buffer, Buffer];
|
|
10
|
+
largeBlob: Buffer;
|
|
9
11
|
}
|
|
10
12
|
declare function getCredential(rpid: string, challenge: Buffer, nativeWindowHandle: Buffer, allowedCredentialIds: Buffer[]): Promise<GetCredentialResult>;
|
|
11
13
|
export { getCredential };
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoBA,KAAK,uBAAuB,GAAG,UAAU,GAAG,gBAAgB,CAAC;AAE7D,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,uBAAuB,EAAE,uBAAuB,CAAC;IACjD,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoBA,KAAK,uBAAuB,GAAG,UAAU,GAAG,gBAAgB,CAAC;AAE7D,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,uBAAuB,EAAE,uBAAuB,CAAC;IACjD,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,iBAAS,aAAa,CACpB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,kBAAkB,EAAE,MAAM,EAC1B,oBAAoB,EAAE,MAAM,EAAE,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CAiG9B;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -40,6 +40,9 @@ function getCredential(rpid, challenge, nativeWindowHandle, allowedCredentialIds
|
|
|
40
40
|
ASAuthorizationPublicKeyCredentialAttachment.ASAuthorizationPublicKeyCredentialAttachmentCrossPlatform) {
|
|
41
41
|
authenticatorAttachment = "cross-platform";
|
|
42
42
|
}
|
|
43
|
+
const prf = credential.prf();
|
|
44
|
+
const prfFirst = prf.first();
|
|
45
|
+
const prfSecond = prf.second();
|
|
43
46
|
resolve({
|
|
44
47
|
id,
|
|
45
48
|
authenticatorAttachment,
|
|
@@ -47,6 +50,11 @@ function getCredential(rpid, challenge, nativeWindowHandle, allowedCredentialIds
|
|
|
47
50
|
authenticatorData: bufferFromNSDataDirect(credential.rawAuthenticatorData()),
|
|
48
51
|
signature: bufferFromNSDataDirect(credential.signature()),
|
|
49
52
|
userHandle: bufferFromNSDataDirect(credential.userID()),
|
|
53
|
+
prf: [
|
|
54
|
+
bufferFromNSDataDirect(prfFirst),
|
|
55
|
+
bufferFromNSDataDirect(prfSecond),
|
|
56
|
+
],
|
|
57
|
+
largeBlob: bufferFromNSDataDirect(credential.largeBlob().readData()),
|
|
50
58
|
});
|
|
51
59
|
},
|
|
52
60
|
didCompleteWithError: (_, error) => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,qCAAqC,EAAE,MAAM,wEAAwE,CAAC;AAC/H,OAAO,EAAE,6BAA6B,EAAE,MAAM,+DAA+D,CAAC;AAC9G,OAAO,EAAE,iCAAiC,EAAE,MAAM,8FAA8F,CAAC;AACjJ,OAAO,EAAE,yCAAyC,EAAE,MAAM,4FAA4F,CAAC;AACvJ,OAAO,EAAE,2CAA2C,EAAE,MAAM,8FAA8F,CAAC;AAG3J,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAEL,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,4CAA4C,EAAE,MAAM,2FAA2F,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example.d.ts","sourceRoot":"","sources":["../../src/test/example.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { NSData } from "../objc/foundation/nsdata.js";
|
|
2
|
+
import { NSString } from "../objc/foundation/nsstring.js";
|
|
3
|
+
import { NSArray } from "../objc/foundation/nsarray.js";
|
|
4
|
+
const myString = NSString.stringWithUTF8String$("Hello from Objective-C!");
|
|
5
|
+
console.log("Created NSString:", myString);
|
|
6
|
+
const buf = Buffer.from("Hello from Objective-C!");
|
|
7
|
+
const myData = NSData.dataWithBytes$length$(buf, buf.length);
|
|
8
|
+
console.log("Created NSData:", myData);
|
|
9
|
+
// Test NSArray
|
|
10
|
+
const str1 = NSString.stringWithUTF8String$("First");
|
|
11
|
+
const str2 = NSString.stringWithUTF8String$("Second");
|
|
12
|
+
const str3 = NSString.stringWithUTF8String$("Third");
|
|
13
|
+
// Create array with one object, then add more
|
|
14
|
+
let myArray = NSArray.arrayWithObject$(str1);
|
|
15
|
+
myArray = myArray.arrayByAddingObject$(str2);
|
|
16
|
+
myArray = myArray.arrayByAddingObject$(str3);
|
|
17
|
+
console.log("Created NSArray with count:", myArray.count());
|
|
18
|
+
// Access elements
|
|
19
|
+
for (let i = 0; i < myArray.count(); i++) {
|
|
20
|
+
const obj = myArray.objectAtIndex$(i);
|
|
21
|
+
const nsString = obj;
|
|
22
|
+
console.log(`Array[${i}]:`, nsString.UTF8String());
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=example.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example.js","sourceRoot":"","sources":["../../src/test/example.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAExD,MAAM,QAAQ,GAAG,QAAQ,CAAC,qBAAqB,CAAC,yBAAyB,CAAC,CAAC;AAC3E,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;AAE3C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;AACnD,MAAM,MAAM,GAAG,MAAM,CAAC,qBAAqB,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;AAC7D,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;AAEvC,eAAe;AACf,MAAM,IAAI,GAAG,QAAQ,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;AACrD,MAAM,IAAI,GAAG,QAAQ,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AACtD,MAAM,IAAI,GAAG,QAAQ,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAErD,8CAA8C;AAC9C,IAAI,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAC7C,OAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;AAC7C,OAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;AAE7C,OAAO,CAAC,GAAG,CAAC,6BAA6B,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;AAE5D,kBAAkB;AAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;IACzC,MAAM,GAAG,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAQ,CAAC;IAC7C,MAAM,QAAQ,GAAG,GAAkB,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { getPointer } from "objc-js";
|
|
2
|
+
import { createEmptyWindow, getNativeWindowHandle } from "./window.js";
|
|
3
|
+
import { getCredential } from "../index.js";
|
|
4
|
+
const window = createEmptyWindow();
|
|
5
|
+
const nsView = getNativeWindowHandle(window);
|
|
6
|
+
const nsViewPointer = getPointer(nsView);
|
|
7
|
+
const result = getCredential("example.com", Buffer.from("challenge"), nsViewPointer, []);
|
|
8
|
+
console.log("Result:", result);
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAC;AACnC,MAAM,MAAM,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAC7C,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;AAEzC,MAAM,MAAM,GAAG,aAAa,CAC1B,aAAa,EACb,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EACxB,aAAa,EACb,EAAE,CACH,CAAC;AACF,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../../src/test/window.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAWxE,iBAAS,iBAAiB,IAAI,WAAW,CAmDxC;AAED,iBAAS,qBAAqB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAG/D;AAED,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { NobjcLibrary, NobjcProtocol } from "objc-js";
|
|
2
|
+
import { allocInitPlain } from "../objc/helpers.js";
|
|
3
|
+
import { NSStringFromString } from "../objc/foundation/nsstring.js";
|
|
4
|
+
const AppKit = new NobjcLibrary("/System/Library/Frameworks/AppKit.framework/AppKit");
|
|
5
|
+
const Foundation = new NobjcLibrary("/System/Library/Frameworks/Foundation.framework/Foundation");
|
|
6
|
+
function createEmptyWindow() {
|
|
7
|
+
const NSApp = AppKit.NSApplication.sharedApplication();
|
|
8
|
+
const window = allocInitPlain(AppKit.NSWindow);
|
|
9
|
+
const styleMask = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3); // titled, closable, miniaturizable, resizable
|
|
10
|
+
// Make the app active and show the window.
|
|
11
|
+
window.setStyleMask$(styleMask);
|
|
12
|
+
window.setFrameFromString$(NSStringFromString("{{100, 100}, {800, 600}}"));
|
|
13
|
+
NSApp.setActivationPolicy$(0);
|
|
14
|
+
NSApp.finishLaunching();
|
|
15
|
+
NSApp.activateIgnoringOtherApps$(true);
|
|
16
|
+
window.setIsVisible$(true);
|
|
17
|
+
window.makeKeyWindow();
|
|
18
|
+
window.orderFrontRegardless();
|
|
19
|
+
const delegate = NobjcProtocol.implement("NSWindowDelegate", {
|
|
20
|
+
windowShouldClose$: () => {
|
|
21
|
+
NSApp.terminate$(NSApp);
|
|
22
|
+
return true;
|
|
23
|
+
},
|
|
24
|
+
windowWillClose$: () => {
|
|
25
|
+
NSApp.terminate$(NSApp);
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
window.setDelegate$(delegate);
|
|
29
|
+
const shutdown = () => {
|
|
30
|
+
try {
|
|
31
|
+
window.close();
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
NSApp.stop$(NSApp);
|
|
35
|
+
NSApp.terminate$(NSApp);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const handleSignal = () => shutdown();
|
|
39
|
+
process.once("exit", shutdown);
|
|
40
|
+
process.once("SIGINT", handleSignal);
|
|
41
|
+
process.once("SIGTERM", handleSignal);
|
|
42
|
+
process.once("SIGQUIT", handleSignal);
|
|
43
|
+
// Pump the AppKit run loop for a short tick to keep JS responsive.
|
|
44
|
+
const runLoop = Foundation.NSRunLoop.currentRunLoop();
|
|
45
|
+
const pump = () => {
|
|
46
|
+
const untilDate = Foundation.NSDate.dateWithTimeIntervalSinceNow$(0.01);
|
|
47
|
+
runLoop.runUntilDate$(untilDate);
|
|
48
|
+
};
|
|
49
|
+
const pumpId = setInterval(pump, 10);
|
|
50
|
+
process.once("exit", () => clearInterval(pumpId));
|
|
51
|
+
return window;
|
|
52
|
+
}
|
|
53
|
+
function getNativeWindowHandle(window) {
|
|
54
|
+
// Electron expects an NSView* on macOS; contentView returns that NSView.
|
|
55
|
+
return window.contentView();
|
|
56
|
+
}
|
|
57
|
+
export { createEmptyWindow, getNativeWindowHandle };
|
|
58
|
+
//# sourceMappingURL=window.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"window.js","sourceRoot":"","sources":["../../src/test/window.ts"],"names":[],"mappings":"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"}
|