@micha.bigler/ui-core-micha 1.4.33 → 1.4.35
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/pages/LoginPage.js +1 -1
- package/dist/utils/authService.js +29 -12
- package/package.json +1 -1
- package/src/pages/LoginPage.jsx +1 -1
- package/src/utils/authService.js +37 -12
package/dist/pages/LoginPage.js
CHANGED
|
@@ -2,6 +2,14 @@ import { getPasskeyRegistrationOptions, completePasskeyRegistration, getPasskeyL
|
|
|
2
2
|
import { ensureWebAuthnSupport, serializeCredential } from '../utils/webauthn';
|
|
3
3
|
import { normaliseApiError } from '../utils/auth-errors';
|
|
4
4
|
import apiClient from '../auth/apiClient';
|
|
5
|
+
import { HEADLESS_BASE } from '../auth/authConfig';
|
|
6
|
+
// HILFSFUNKTION: Entpackt die Optionen, falls sie in 'publicKey' stecken
|
|
7
|
+
function resolveWebAuthnOptions(options) {
|
|
8
|
+
if (options && options.publicKey) {
|
|
9
|
+
return options.publicKey;
|
|
10
|
+
}
|
|
11
|
+
return options;
|
|
12
|
+
}
|
|
5
13
|
export async function registerPasskey(name = 'Passkey') {
|
|
6
14
|
ensureWebAuthnSupport();
|
|
7
15
|
// 1. Get Options from Server
|
|
@@ -9,10 +17,11 @@ export async function registerPasskey(name = 'Passkey') {
|
|
|
9
17
|
// 2. Call Browser API
|
|
10
18
|
let credential;
|
|
11
19
|
try {
|
|
12
|
-
// FIX:
|
|
13
|
-
const
|
|
14
|
-
//
|
|
15
|
-
|
|
20
|
+
// FIX: Erst entpacken (JSON -> JSON ohne publicKey Wrapper)
|
|
21
|
+
const optionsJson = resolveWebAuthnOptions(creationOptions);
|
|
22
|
+
// Dann parsen (JSON -> ArrayBuffer)
|
|
23
|
+
const publicKeyOptions = window.PublicKeyCredential.parseCreationOptionsFromJSON(creationOptions);
|
|
24
|
+
credential = await navigator.credentials.create({ publicKey: publicKeyOptions });
|
|
16
25
|
}
|
|
17
26
|
catch (err) {
|
|
18
27
|
if (err.name === 'NotAllowedError') {
|
|
@@ -31,10 +40,11 @@ export async function loginWithPasskey() {
|
|
|
31
40
|
// 2. Browser Sign
|
|
32
41
|
let assertion;
|
|
33
42
|
try {
|
|
34
|
-
// FIX:
|
|
35
|
-
const
|
|
36
|
-
//
|
|
37
|
-
|
|
43
|
+
// FIX: Erst entpacken
|
|
44
|
+
const optionsJson = resolveWebAuthnOptions(requestOptions);
|
|
45
|
+
// Dann parsen
|
|
46
|
+
const publicKeyOptions = window.PublicKeyCredential.parseRequestOptionsFromJSON(optionsJson);
|
|
47
|
+
assertion = await navigator.credentials.get({ publicKey: publicKeyOptions });
|
|
38
48
|
}
|
|
39
49
|
catch (err) {
|
|
40
50
|
if (err.name === 'NotAllowedError') {
|
|
@@ -56,7 +66,11 @@ export async function authenticateMfaWithPasskey() {
|
|
|
56
66
|
ensureWebAuthnSupport();
|
|
57
67
|
let requestOptions;
|
|
58
68
|
try {
|
|
59
|
-
const
|
|
69
|
+
const url = typeof HEADLESS_BASE !== 'undefined'
|
|
70
|
+
? `${HEADLESS_BASE}/auth/2fa/authenticate`
|
|
71
|
+
: '/api/auth/browser/v1/auth/2fa/authenticate';
|
|
72
|
+
const res = await apiClient.get(url);
|
|
73
|
+
// Allauth liefert oft: { data: { request_options: { publicKey: ... } } }
|
|
60
74
|
const data = ((_a = res.data) === null || _a === void 0 ? void 0 : _a.data) || res.data;
|
|
61
75
|
requestOptions = data.request_options || data;
|
|
62
76
|
}
|
|
@@ -69,9 +83,12 @@ export async function authenticateMfaWithPasskey() {
|
|
|
69
83
|
// 2. Browser Sign
|
|
70
84
|
let assertion;
|
|
71
85
|
try {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
86
|
+
// FIX: Erst entpacken
|
|
87
|
+
const optionsJson = resolveWebAuthnOptions(requestOptions);
|
|
88
|
+
// Dann parsen
|
|
89
|
+
const publicKeyOptions = window.PublicKeyCredential.parseRequestOptionsFromJSON(optionsJson);
|
|
90
|
+
// Dann wrappen
|
|
91
|
+
assertion = await navigator.credentials.get({ publicKey: publicKeyOptions });
|
|
75
92
|
}
|
|
76
93
|
catch (err) {
|
|
77
94
|
if (err.name === 'NotAllowedError') {
|
package/package.json
CHANGED
package/src/pages/LoginPage.jsx
CHANGED
|
@@ -92,7 +92,7 @@ export function LoginPage() {
|
|
|
92
92
|
setSubmitting(true);
|
|
93
93
|
try {
|
|
94
94
|
// Service handles browser interaction + API calls
|
|
95
|
-
const
|
|
95
|
+
const user = await loginWithPasskey();
|
|
96
96
|
handleLoginSuccess(user);
|
|
97
97
|
} catch (err) {
|
|
98
98
|
// 'Auth.PASSKEY_CANCELLED' is generic, maybe ignore visually or show specific hint
|
package/src/utils/authService.js
CHANGED
|
@@ -13,6 +13,15 @@ import {
|
|
|
13
13
|
} from '../utils/webauthn';
|
|
14
14
|
import { normaliseApiError } from '../utils/auth-errors';
|
|
15
15
|
import apiClient from '../auth/apiClient';
|
|
16
|
+
import { HEADLESS_BASE } from '../auth/authConfig';
|
|
17
|
+
|
|
18
|
+
// HILFSFUNKTION: Entpackt die Optionen, falls sie in 'publicKey' stecken
|
|
19
|
+
function resolveWebAuthnOptions(options) {
|
|
20
|
+
if (options && options.publicKey) {
|
|
21
|
+
return options.publicKey;
|
|
22
|
+
}
|
|
23
|
+
return options;
|
|
24
|
+
}
|
|
16
25
|
|
|
17
26
|
export async function registerPasskey(name = 'Passkey') {
|
|
18
27
|
ensureWebAuthnSupport();
|
|
@@ -23,10 +32,13 @@ export async function registerPasskey(name = 'Passkey') {
|
|
|
23
32
|
// 2. Call Browser API
|
|
24
33
|
let credential;
|
|
25
34
|
try {
|
|
26
|
-
// FIX:
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
35
|
+
// FIX: Erst entpacken (JSON -> JSON ohne publicKey Wrapper)
|
|
36
|
+
const optionsJson = resolveWebAuthnOptions(creationOptions);
|
|
37
|
+
|
|
38
|
+
// Dann parsen (JSON -> ArrayBuffer)
|
|
39
|
+
const publicKeyOptions =
|
|
40
|
+
window.PublicKeyCredential.parseCreationOptionsFromJSON(creationOptions);
|
|
41
|
+
credential = await navigator.credentials.create({ publicKey: publicKeyOptions });
|
|
30
42
|
} catch (err) {
|
|
31
43
|
if (err.name === 'NotAllowedError') {
|
|
32
44
|
throw normaliseApiError(new Error('Auth.PASSKEY_CANCELLED'), 'Auth.PASSKEY_CANCELLED');
|
|
@@ -48,10 +60,13 @@ export async function loginWithPasskey() {
|
|
|
48
60
|
// 2. Browser Sign
|
|
49
61
|
let assertion;
|
|
50
62
|
try {
|
|
51
|
-
// FIX:
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
63
|
+
// FIX: Erst entpacken
|
|
64
|
+
const optionsJson = resolveWebAuthnOptions(requestOptions);
|
|
65
|
+
|
|
66
|
+
// Dann parsen
|
|
67
|
+
const publicKeyOptions =
|
|
68
|
+
window.PublicKeyCredential.parseRequestOptionsFromJSON(optionsJson);
|
|
69
|
+
assertion = await navigator.credentials.get({ publicKey: publicKeyOptions });
|
|
55
70
|
} catch (err) {
|
|
56
71
|
if (err.name === 'NotAllowedError') {
|
|
57
72
|
throw normaliseApiError(new Error('Auth.PASSKEY_CANCELLED'), 'Auth.PASSKEY_CANCELLED');
|
|
@@ -75,7 +90,12 @@ export async function authenticateMfaWithPasskey() {
|
|
|
75
90
|
|
|
76
91
|
let requestOptions;
|
|
77
92
|
try {
|
|
78
|
-
const
|
|
93
|
+
const url = typeof HEADLESS_BASE !== 'undefined'
|
|
94
|
+
? `${HEADLESS_BASE}/auth/2fa/authenticate`
|
|
95
|
+
: '/api/auth/browser/v1/auth/2fa/authenticate';
|
|
96
|
+
|
|
97
|
+
const res = await apiClient.get(url);
|
|
98
|
+
// Allauth liefert oft: { data: { request_options: { publicKey: ... } } }
|
|
79
99
|
const data = res.data?.data || res.data;
|
|
80
100
|
requestOptions = data.request_options || data;
|
|
81
101
|
} catch (err) {
|
|
@@ -89,9 +109,14 @@ export async function authenticateMfaWithPasskey() {
|
|
|
89
109
|
// 2. Browser Sign
|
|
90
110
|
let assertion;
|
|
91
111
|
try {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
112
|
+
// FIX: Erst entpacken
|
|
113
|
+
const optionsJson = resolveWebAuthnOptions(requestOptions);
|
|
114
|
+
|
|
115
|
+
// Dann parsen
|
|
116
|
+
const publicKeyOptions = window.PublicKeyCredential.parseRequestOptionsFromJSON(optionsJson);
|
|
117
|
+
|
|
118
|
+
// Dann wrappen
|
|
119
|
+
assertion = await navigator.credentials.get({ publicKey: publicKeyOptions });
|
|
95
120
|
} catch (err) {
|
|
96
121
|
if (err.name === 'NotAllowedError') {
|
|
97
122
|
throw normaliseApiError(new Error('Auth.PASSKEY_CANCELLED'), 'Auth.PASSKEY_CANCELLED');
|