@adminforth/two-factors-auth 3.2.1 → 3.2.2
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/build.log +2 -2
- package/custom/TwoFAModal.vue +17 -13
- package/custom/TwoFactorsConfirmation.vue +5 -5
- package/custom/TwoFactorsPasskeysSettings.vue +23 -23
- package/dist/custom/TwoFAModal.vue +17 -13
- package/dist/custom/TwoFactorsConfirmation.vue +5 -5
- package/dist/custom/TwoFactorsPasskeysSettings.vue +23 -23
- package/package.json +1 -1
package/build.log
CHANGED
|
@@ -16,5 +16,5 @@ custom/pnpm-lock.yaml
|
|
|
16
16
|
custom/tsconfig.json
|
|
17
17
|
custom/utils.js
|
|
18
18
|
|
|
19
|
-
sent 285,
|
|
20
|
-
total size is 284,
|
|
19
|
+
sent 285,475 bytes received 229 bytes 571,408.00 bytes/sec
|
|
20
|
+
total size is 284,569 speedup is 1.00
|
package/custom/TwoFAModal.vue
CHANGED
|
@@ -41,7 +41,9 @@
|
|
|
41
41
|
{{$t('Having trouble?')}}
|
|
42
42
|
<button type="button" class="af-2fa-switch-to-passkey text-lightPrimary dark:text-white hover:underline cursor-pointer" @click="modalMode = 'passkey'">{{$t('Use passkey instead')}}</button>
|
|
43
43
|
</p>
|
|
44
|
-
<p class="af-2fa-multiple-actions text-center text-red-500 text-xs" v-if="sessionsIdsToResolve.length > 1">
|
|
44
|
+
<p class="af-2fa-multiple-actions text-center text-red-500 text-xs" v-if="sessionsIdsToResolve.length > 1">
|
|
45
|
+
{{ $t('You are confirming {count} action | You are confirming {count} actions', sessionsIdsToResolve.length) }}
|
|
46
|
+
</p>
|
|
45
47
|
</div>
|
|
46
48
|
|
|
47
49
|
<div v-else-if="modalMode === 'passkey'" class="af-two-factor-modal-passkeys flex flex-col gap-4 relative bg-white dark:bg-gray-700 rounded-lg shadow p-6 w-full max-w-md">
|
|
@@ -89,7 +91,9 @@
|
|
|
89
91
|
{{$t('Having trouble?')}}
|
|
90
92
|
<button type="button" class="af-2fa-switch-to-totp text-lightPrimary dark:text-white hover:underline cursor-pointer" @click="modalMode = 'totp'">{{$t('Use TOTP instead')}}</button>
|
|
91
93
|
</p>
|
|
92
|
-
<p class="af-2fa-multiple-actions text-center text-red-500 text-xs" v-if="sessionsIdsToResolve.length > 1">
|
|
94
|
+
<p class="af-2fa-multiple-actions text-center text-red-500 text-xs" v-if="sessionsIdsToResolve.length > 1">
|
|
95
|
+
{{ $t('You are confirming {count} action | You are confirming {count} actions', sessionsIdsToResolve.length) }}
|
|
96
|
+
</p>
|
|
93
97
|
</div>
|
|
94
98
|
</div>
|
|
95
99
|
</template>
|
|
@@ -148,7 +152,7 @@
|
|
|
148
152
|
websocket.unsubscribeByPrefix(`/user2fa/`);
|
|
149
153
|
websocket.subscribe(`/user2fa/${props.adminUser.pk}`, async (data: {sessionId: string}) => {
|
|
150
154
|
if (!allowAddNewSessions) {
|
|
151
|
-
alert({message: 'Some process or user tries to add new actions to confirm. Action was blocked', variant: 'warning'});
|
|
155
|
+
alert({message: t('Some process or user tries to add new actions to confirm. Action was blocked'), variant: 'warning'});
|
|
152
156
|
return;
|
|
153
157
|
}
|
|
154
158
|
sessionsIdsToResolve.value.push(data.sessionId);
|
|
@@ -160,7 +164,7 @@
|
|
|
160
164
|
isAwaiting2FAResult.value = true;
|
|
161
165
|
confirmationResult = await window.adminforthTwoFaModal.get2FaConfirmationResult();
|
|
162
166
|
} catch (error) {
|
|
163
|
-
console.error('Error during 2FA confirmation:', error);
|
|
167
|
+
console.error(t('Error during 2FA confirmation:', error));
|
|
164
168
|
}
|
|
165
169
|
isAwaiting2FAResult.value = false;
|
|
166
170
|
try {
|
|
@@ -170,15 +174,15 @@
|
|
|
170
174
|
body: { confirmationResult, sessionsIds: sessionsIdsToResolve.value }
|
|
171
175
|
});
|
|
172
176
|
if (!response.ok && response.error === 'No session ID or confirmation result'){
|
|
173
|
-
alert({message: 'Verification session finished or cancelled.', variant: 'warning'});
|
|
177
|
+
alert({message: t('Verification session finished or cancelled.'), variant: 'warning'});
|
|
174
178
|
} else if (!response.ok) {
|
|
175
|
-
alert({message: 'Verification failed', variant: 'danger'});
|
|
179
|
+
alert({message: t('Verification failed'), variant: 'danger'});
|
|
176
180
|
} else if (response.ok) {
|
|
177
|
-
alert({message: 'Verification successful', variant: 'success'});
|
|
181
|
+
alert({message: t('Verification successful'), variant: 'success'});
|
|
178
182
|
}
|
|
179
183
|
sessionsIdsToResolve.value = [];
|
|
180
184
|
} catch (error) {
|
|
181
|
-
console.error('Error resolving automatic 2FA verification:', error);
|
|
185
|
+
console.error(t('Error resolving automatic 2FA verification:', error));
|
|
182
186
|
}
|
|
183
187
|
allowAddNewSessions = true;
|
|
184
188
|
});
|
|
@@ -226,7 +230,7 @@
|
|
|
226
230
|
window.adminforthTwoFaModal = {
|
|
227
231
|
get2FaConfirmationResult: (title?: string, verifyingCallback?: (confirmationResult: string) => Promise<boolean>) =>
|
|
228
232
|
new Promise(async (resolve, reject) => {
|
|
229
|
-
if (modelShow.value) throw new Error('Modal is already open');
|
|
233
|
+
if (modelShow.value) throw new Error(t('Modal is already open'));
|
|
230
234
|
const skipAllowModal = await checkIfSkipAllowModal();
|
|
231
235
|
if (skipAllowModal) {
|
|
232
236
|
resolve({ code: "123456" }); // dummy code
|
|
@@ -303,12 +307,12 @@
|
|
|
303
307
|
}
|
|
304
308
|
|
|
305
309
|
async function sendConfirmationResult(value: string) {
|
|
306
|
-
if (!resolveFn) throw new Error('Modal is not initialized properly');
|
|
310
|
+
if (!resolveFn) throw new Error(t('Modal is not initialized properly'));
|
|
307
311
|
if (verifyFn) {
|
|
308
312
|
try {
|
|
309
313
|
const ok = await verifyFn(value);
|
|
310
314
|
if (!ok) {
|
|
311
|
-
rejectFn?.(new Error('Invalid code'));
|
|
315
|
+
rejectFn?.(new Error(t('Invalid code')));
|
|
312
316
|
return;
|
|
313
317
|
}
|
|
314
318
|
} catch (err) {
|
|
@@ -393,7 +397,7 @@
|
|
|
393
397
|
}
|
|
394
398
|
}
|
|
395
399
|
} catch (error) {
|
|
396
|
-
console.error('Error checking passkeys:', error);
|
|
400
|
+
console.error(t('Error checking passkeys:', error));
|
|
397
401
|
// Fallback to TOTP if there's an error
|
|
398
402
|
doesUserHavePasskeys.value = false;
|
|
399
403
|
modalMode.value = "totp";
|
|
@@ -455,7 +459,7 @@
|
|
|
455
459
|
return false;
|
|
456
460
|
}
|
|
457
461
|
} catch (error) {
|
|
458
|
-
console.error('Error checking skip allow modal:', error);
|
|
462
|
+
console.error(t('Error checking skip allow modal:', error));
|
|
459
463
|
return false;
|
|
460
464
|
}
|
|
461
465
|
}
|
|
@@ -299,7 +299,7 @@
|
|
|
299
299
|
}
|
|
300
300
|
});
|
|
301
301
|
} catch (error) {
|
|
302
|
-
console.error('Error checking if user has passkeys:', error);
|
|
302
|
+
console.error(t('Error checking if user has passkeys:', error));
|
|
303
303
|
}
|
|
304
304
|
}
|
|
305
305
|
|
|
@@ -318,7 +318,7 @@
|
|
|
318
318
|
try {
|
|
319
319
|
options = PublicKeyCredential.parseRequestOptionsFromJSON(_options);
|
|
320
320
|
} catch (e) {
|
|
321
|
-
console.error('Error parsing request options:', e);
|
|
321
|
+
console.error(t('Error parsing request options:', e));
|
|
322
322
|
adminforth.alert({message: t('Error initiating passkey authentication.'), variant: 'warning'});
|
|
323
323
|
return;
|
|
324
324
|
}
|
|
@@ -345,14 +345,14 @@
|
|
|
345
345
|
method: 'POST',
|
|
346
346
|
});
|
|
347
347
|
} catch (error) {
|
|
348
|
-
console.error('Error creating sign-in request:', error);
|
|
348
|
+
console.error(t('Error creating sign-in request:', error));
|
|
349
349
|
return;
|
|
350
350
|
}
|
|
351
351
|
if (response.ok === true) {
|
|
352
352
|
return { _options: response.data, challengeId: response.challengeId };
|
|
353
353
|
} else {
|
|
354
354
|
adminforth.alert({message: t('Error creating sign-in request.'), variant: 'warning'});
|
|
355
|
-
codeError.value = 'Error creating sign-in request.';
|
|
355
|
+
codeError.value = t('Error creating sign-in request.');
|
|
356
356
|
}
|
|
357
357
|
}
|
|
358
358
|
|
|
@@ -378,7 +378,7 @@
|
|
|
378
378
|
});
|
|
379
379
|
return credential;
|
|
380
380
|
} catch (error) {
|
|
381
|
-
console.error('Error during authentication:', error);
|
|
381
|
+
console.error(t('Error during authentication:', error));
|
|
382
382
|
// Handle specific concurrent/pending request error cases gracefully
|
|
383
383
|
const name = (error && (error.name || error.constructor?.name)) || '';
|
|
384
384
|
const message = (error && error.message) || '';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="af-passkeys flex flex-col justify-center mr-6 md:mr-12">
|
|
3
3
|
<h2 class="af-passkeys-title flex items-start justify-start leading-none text-gray-800 dark:text-gray-50 text-3xl font-semibold">{{$t('Passkeys')}}</h2>
|
|
4
|
-
<p class="af-passkeys-subtitle text-sm mt-3">Manage your passwordless authentication methods</p>
|
|
4
|
+
<p class="af-passkeys-subtitle text-sm mt-3"> {{$t('Manage your passwordless authentication methods')}} </p>
|
|
5
5
|
|
|
6
6
|
<div class="af-passkeys-grid mt-6 flex flex-wrap gap-4">
|
|
7
7
|
<div
|
|
@@ -177,13 +177,13 @@
|
|
|
177
177
|
isFetchingPasskey.value = true;
|
|
178
178
|
try {
|
|
179
179
|
const confirmationResult = await window.adminforthTwoFaModal
|
|
180
|
-
.get2FaConfirmationResult('To add passkey first verify yourself');
|
|
180
|
+
.get2FaConfirmationResult(t('To add passkey first verify yourself'));
|
|
181
181
|
|
|
182
182
|
if (!confirmationResult) return;
|
|
183
183
|
|
|
184
184
|
const { options, error } = await requestPasskeyChallenge(confirmationResult);
|
|
185
185
|
if (!options) {
|
|
186
|
-
adminforth.alert({ message: error ?? 'Verification failed.', variant: 'warning' });
|
|
186
|
+
adminforth.alert({ message: error ?? t('Verification failed.'), variant: 'warning' });
|
|
187
187
|
return;
|
|
188
188
|
}
|
|
189
189
|
|
|
@@ -210,9 +210,9 @@
|
|
|
210
210
|
passkeys.value = response.data;
|
|
211
211
|
authenticatorAttachment.value = response.authenticatorAttachment;
|
|
212
212
|
} catch (error) {
|
|
213
|
-
console.error('Error fetching passkeys:', error);
|
|
213
|
+
console.error(t('Error fetching passkeys:'), error);
|
|
214
214
|
if (coreStore.adminUser?.username) {
|
|
215
|
-
adminforth.alert({ message: 'Error fetching passkeys.', variant: 'warning' });
|
|
215
|
+
adminforth.alert({ message: t('Error fetching passkeys.'), variant: 'warning' });
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
}
|
|
@@ -226,12 +226,12 @@
|
|
|
226
226
|
method: 'POST',
|
|
227
227
|
body: { mode: addPasskeyMode.value, confirmationResult },
|
|
228
228
|
});
|
|
229
|
-
if (!response.ok) return { error: response.error ?? 'Verification failed' };
|
|
229
|
+
if (!response.ok) return { error: response.error ?? t('Verification failed') };
|
|
230
230
|
const options = PublicKeyCredential.parseCreationOptionsFromJSON(response.data);
|
|
231
231
|
return { options, challengeId: response.challengeId };
|
|
232
232
|
} catch (error) {
|
|
233
|
-
console.error('Error requesting passkey challenge:', error);
|
|
234
|
-
return { error: 'Failed to request passkey challenge' };
|
|
233
|
+
console.error(t('Error requesting passkey challenge:', error));
|
|
234
|
+
return { error: t('Failed to request passkey challenge' )};
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
237
|
|
|
@@ -240,8 +240,8 @@
|
|
|
240
240
|
const credential = await navigator.credentials.create({ publicKey: options });
|
|
241
241
|
return JSON.stringify((credential as PublicKeyCredential).toJSON());
|
|
242
242
|
} catch (error) {
|
|
243
|
-
console.error('Error creating WebAuthn credential:', error);
|
|
244
|
-
adminforth.alert({ message: 'Error creating passkey.', variant: 'warning' });
|
|
243
|
+
console.error(t('Error creating WebAuthn credential:', error));
|
|
244
|
+
adminforth.alert({ message: t('Error creating passkey.'), variant: 'warning' });
|
|
245
245
|
return null;
|
|
246
246
|
}
|
|
247
247
|
}
|
|
@@ -254,13 +254,13 @@
|
|
|
254
254
|
body: { credential, origin: window.location.origin },
|
|
255
255
|
});
|
|
256
256
|
if (res.ok) {
|
|
257
|
-
adminforth.alert({ message: 'Passkey registered successfully!', variant: 'success' });
|
|
257
|
+
adminforth.alert({ message: t('Passkey registered successfully!'), variant: 'success' });
|
|
258
258
|
getPasskeys();
|
|
259
259
|
} else {
|
|
260
|
-
adminforth.alert({ message: 'Error registering passkey.', variant: 'warning' });
|
|
260
|
+
adminforth.alert({ message: t('Error registering passkey.'), variant: 'warning' });
|
|
261
261
|
}
|
|
262
262
|
} catch (error) {
|
|
263
|
-
console.error('Error registering passkey:', error);
|
|
263
|
+
console.error(t('Error registering passkey:', error));
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
266
|
|
|
@@ -283,15 +283,15 @@
|
|
|
283
283
|
body: { passkeyId },
|
|
284
284
|
});
|
|
285
285
|
if (response.ok) {
|
|
286
|
-
adminforth.alert({ message: 'Passkey deleted successfully!', variant: 'success' });
|
|
286
|
+
adminforth.alert({ message: t('Passkey deleted successfully!'), variant: 'success' });
|
|
287
287
|
getPasskeys();
|
|
288
288
|
} else {
|
|
289
|
-
console.error('Error deleting passkey:', response?.error);
|
|
290
|
-
adminforth.alert({ message: 'Error deleting passkey.', variant: 'warning' });
|
|
289
|
+
console.error(t('Error deleting passkey:', response?.error));
|
|
290
|
+
adminforth.alert({ message: t('Error deleting passkey.'), variant: 'warning' });
|
|
291
291
|
}
|
|
292
292
|
} catch (error) {
|
|
293
|
-
console.error('Error deleting passkey:', error);
|
|
294
|
-
adminforth.alert({ message: 'Error deleting passkey.', variant: 'warning' });
|
|
293
|
+
console.error(t('Error deleting passkey:', error));
|
|
294
|
+
adminforth.alert({ message: t('Error deleting passkey.'), variant: 'warning' });
|
|
295
295
|
}
|
|
296
296
|
}
|
|
297
297
|
|
|
@@ -303,15 +303,15 @@
|
|
|
303
303
|
body: { passkeyId, newName: name },
|
|
304
304
|
});
|
|
305
305
|
if (response.ok) {
|
|
306
|
-
adminforth.alert({ message: 'Passkey updated successfully!', variant: 'success' });
|
|
306
|
+
adminforth.alert({ message: t('Passkey updated successfully!'), variant: 'success' });
|
|
307
307
|
getPasskeys();
|
|
308
308
|
} else {
|
|
309
|
-
console.error('Error updating passkey:', response.error);
|
|
310
|
-
adminforth.alert({ message: 'Error updating passkey.', variant: 'warning' });
|
|
309
|
+
console.error(t('Error updating passkey:', response.error));
|
|
310
|
+
adminforth.alert({ message: t('Error updating passkey.'), variant: 'warning' });
|
|
311
311
|
}
|
|
312
312
|
} catch (error) {
|
|
313
|
-
console.error('Error updating passkey:', error);
|
|
314
|
-
adminforth.alert({ message: 'Error updating passkey.', variant: 'warning' });
|
|
313
|
+
console.error(t('Error updating passkey:', error));
|
|
314
|
+
adminforth.alert({ message: t('Error updating passkey.'), variant: 'warning' });
|
|
315
315
|
}
|
|
316
316
|
}
|
|
317
317
|
|
|
@@ -41,7 +41,9 @@
|
|
|
41
41
|
{{$t('Having trouble?')}}
|
|
42
42
|
<button type="button" class="af-2fa-switch-to-passkey text-lightPrimary dark:text-white hover:underline cursor-pointer" @click="modalMode = 'passkey'">{{$t('Use passkey instead')}}</button>
|
|
43
43
|
</p>
|
|
44
|
-
<p class="af-2fa-multiple-actions text-center text-red-500 text-xs" v-if="sessionsIdsToResolve.length > 1">
|
|
44
|
+
<p class="af-2fa-multiple-actions text-center text-red-500 text-xs" v-if="sessionsIdsToResolve.length > 1">
|
|
45
|
+
{{ $t('You are confirming {count} action | You are confirming {count} actions', sessionsIdsToResolve.length) }}
|
|
46
|
+
</p>
|
|
45
47
|
</div>
|
|
46
48
|
|
|
47
49
|
<div v-else-if="modalMode === 'passkey'" class="af-two-factor-modal-passkeys flex flex-col gap-4 relative bg-white dark:bg-gray-700 rounded-lg shadow p-6 w-full max-w-md">
|
|
@@ -89,7 +91,9 @@
|
|
|
89
91
|
{{$t('Having trouble?')}}
|
|
90
92
|
<button type="button" class="af-2fa-switch-to-totp text-lightPrimary dark:text-white hover:underline cursor-pointer" @click="modalMode = 'totp'">{{$t('Use TOTP instead')}}</button>
|
|
91
93
|
</p>
|
|
92
|
-
<p class="af-2fa-multiple-actions text-center text-red-500 text-xs" v-if="sessionsIdsToResolve.length > 1">
|
|
94
|
+
<p class="af-2fa-multiple-actions text-center text-red-500 text-xs" v-if="sessionsIdsToResolve.length > 1">
|
|
95
|
+
{{ $t('You are confirming {count} action | You are confirming {count} actions', sessionsIdsToResolve.length) }}
|
|
96
|
+
</p>
|
|
93
97
|
</div>
|
|
94
98
|
</div>
|
|
95
99
|
</template>
|
|
@@ -148,7 +152,7 @@
|
|
|
148
152
|
websocket.unsubscribeByPrefix(`/user2fa/`);
|
|
149
153
|
websocket.subscribe(`/user2fa/${props.adminUser.pk}`, async (data: {sessionId: string}) => {
|
|
150
154
|
if (!allowAddNewSessions) {
|
|
151
|
-
alert({message: 'Some process or user tries to add new actions to confirm. Action was blocked', variant: 'warning'});
|
|
155
|
+
alert({message: t('Some process or user tries to add new actions to confirm. Action was blocked'), variant: 'warning'});
|
|
152
156
|
return;
|
|
153
157
|
}
|
|
154
158
|
sessionsIdsToResolve.value.push(data.sessionId);
|
|
@@ -160,7 +164,7 @@
|
|
|
160
164
|
isAwaiting2FAResult.value = true;
|
|
161
165
|
confirmationResult = await window.adminforthTwoFaModal.get2FaConfirmationResult();
|
|
162
166
|
} catch (error) {
|
|
163
|
-
console.error('Error during 2FA confirmation:', error);
|
|
167
|
+
console.error(t('Error during 2FA confirmation:', error));
|
|
164
168
|
}
|
|
165
169
|
isAwaiting2FAResult.value = false;
|
|
166
170
|
try {
|
|
@@ -170,15 +174,15 @@
|
|
|
170
174
|
body: { confirmationResult, sessionsIds: sessionsIdsToResolve.value }
|
|
171
175
|
});
|
|
172
176
|
if (!response.ok && response.error === 'No session ID or confirmation result'){
|
|
173
|
-
alert({message: 'Verification session finished or cancelled.', variant: 'warning'});
|
|
177
|
+
alert({message: t('Verification session finished or cancelled.'), variant: 'warning'});
|
|
174
178
|
} else if (!response.ok) {
|
|
175
|
-
alert({message: 'Verification failed', variant: 'danger'});
|
|
179
|
+
alert({message: t('Verification failed'), variant: 'danger'});
|
|
176
180
|
} else if (response.ok) {
|
|
177
|
-
alert({message: 'Verification successful', variant: 'success'});
|
|
181
|
+
alert({message: t('Verification successful'), variant: 'success'});
|
|
178
182
|
}
|
|
179
183
|
sessionsIdsToResolve.value = [];
|
|
180
184
|
} catch (error) {
|
|
181
|
-
console.error('Error resolving automatic 2FA verification:', error);
|
|
185
|
+
console.error(t('Error resolving automatic 2FA verification:', error));
|
|
182
186
|
}
|
|
183
187
|
allowAddNewSessions = true;
|
|
184
188
|
});
|
|
@@ -226,7 +230,7 @@
|
|
|
226
230
|
window.adminforthTwoFaModal = {
|
|
227
231
|
get2FaConfirmationResult: (title?: string, verifyingCallback?: (confirmationResult: string) => Promise<boolean>) =>
|
|
228
232
|
new Promise(async (resolve, reject) => {
|
|
229
|
-
if (modelShow.value) throw new Error('Modal is already open');
|
|
233
|
+
if (modelShow.value) throw new Error(t('Modal is already open'));
|
|
230
234
|
const skipAllowModal = await checkIfSkipAllowModal();
|
|
231
235
|
if (skipAllowModal) {
|
|
232
236
|
resolve({ code: "123456" }); // dummy code
|
|
@@ -303,12 +307,12 @@
|
|
|
303
307
|
}
|
|
304
308
|
|
|
305
309
|
async function sendConfirmationResult(value: string) {
|
|
306
|
-
if (!resolveFn) throw new Error('Modal is not initialized properly');
|
|
310
|
+
if (!resolveFn) throw new Error(t('Modal is not initialized properly'));
|
|
307
311
|
if (verifyFn) {
|
|
308
312
|
try {
|
|
309
313
|
const ok = await verifyFn(value);
|
|
310
314
|
if (!ok) {
|
|
311
|
-
rejectFn?.(new Error('Invalid code'));
|
|
315
|
+
rejectFn?.(new Error(t('Invalid code')));
|
|
312
316
|
return;
|
|
313
317
|
}
|
|
314
318
|
} catch (err) {
|
|
@@ -393,7 +397,7 @@
|
|
|
393
397
|
}
|
|
394
398
|
}
|
|
395
399
|
} catch (error) {
|
|
396
|
-
console.error('Error checking passkeys:', error);
|
|
400
|
+
console.error(t('Error checking passkeys:', error));
|
|
397
401
|
// Fallback to TOTP if there's an error
|
|
398
402
|
doesUserHavePasskeys.value = false;
|
|
399
403
|
modalMode.value = "totp";
|
|
@@ -455,7 +459,7 @@
|
|
|
455
459
|
return false;
|
|
456
460
|
}
|
|
457
461
|
} catch (error) {
|
|
458
|
-
console.error('Error checking skip allow modal:', error);
|
|
462
|
+
console.error(t('Error checking skip allow modal:', error));
|
|
459
463
|
return false;
|
|
460
464
|
}
|
|
461
465
|
}
|
|
@@ -299,7 +299,7 @@
|
|
|
299
299
|
}
|
|
300
300
|
});
|
|
301
301
|
} catch (error) {
|
|
302
|
-
console.error('Error checking if user has passkeys:', error);
|
|
302
|
+
console.error(t('Error checking if user has passkeys:', error));
|
|
303
303
|
}
|
|
304
304
|
}
|
|
305
305
|
|
|
@@ -318,7 +318,7 @@
|
|
|
318
318
|
try {
|
|
319
319
|
options = PublicKeyCredential.parseRequestOptionsFromJSON(_options);
|
|
320
320
|
} catch (e) {
|
|
321
|
-
console.error('Error parsing request options:', e);
|
|
321
|
+
console.error(t('Error parsing request options:', e));
|
|
322
322
|
adminforth.alert({message: t('Error initiating passkey authentication.'), variant: 'warning'});
|
|
323
323
|
return;
|
|
324
324
|
}
|
|
@@ -345,14 +345,14 @@
|
|
|
345
345
|
method: 'POST',
|
|
346
346
|
});
|
|
347
347
|
} catch (error) {
|
|
348
|
-
console.error('Error creating sign-in request:', error);
|
|
348
|
+
console.error(t('Error creating sign-in request:', error));
|
|
349
349
|
return;
|
|
350
350
|
}
|
|
351
351
|
if (response.ok === true) {
|
|
352
352
|
return { _options: response.data, challengeId: response.challengeId };
|
|
353
353
|
} else {
|
|
354
354
|
adminforth.alert({message: t('Error creating sign-in request.'), variant: 'warning'});
|
|
355
|
-
codeError.value = 'Error creating sign-in request.';
|
|
355
|
+
codeError.value = t('Error creating sign-in request.');
|
|
356
356
|
}
|
|
357
357
|
}
|
|
358
358
|
|
|
@@ -378,7 +378,7 @@
|
|
|
378
378
|
});
|
|
379
379
|
return credential;
|
|
380
380
|
} catch (error) {
|
|
381
|
-
console.error('Error during authentication:', error);
|
|
381
|
+
console.error(t('Error during authentication:', error));
|
|
382
382
|
// Handle specific concurrent/pending request error cases gracefully
|
|
383
383
|
const name = (error && (error.name || error.constructor?.name)) || '';
|
|
384
384
|
const message = (error && error.message) || '';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="af-passkeys flex flex-col justify-center mr-6 md:mr-12">
|
|
3
3
|
<h2 class="af-passkeys-title flex items-start justify-start leading-none text-gray-800 dark:text-gray-50 text-3xl font-semibold">{{$t('Passkeys')}}</h2>
|
|
4
|
-
<p class="af-passkeys-subtitle text-sm mt-3">Manage your passwordless authentication methods</p>
|
|
4
|
+
<p class="af-passkeys-subtitle text-sm mt-3"> {{$t('Manage your passwordless authentication methods')}} </p>
|
|
5
5
|
|
|
6
6
|
<div class="af-passkeys-grid mt-6 flex flex-wrap gap-4">
|
|
7
7
|
<div
|
|
@@ -177,13 +177,13 @@
|
|
|
177
177
|
isFetchingPasskey.value = true;
|
|
178
178
|
try {
|
|
179
179
|
const confirmationResult = await window.adminforthTwoFaModal
|
|
180
|
-
.get2FaConfirmationResult('To add passkey first verify yourself');
|
|
180
|
+
.get2FaConfirmationResult(t('To add passkey first verify yourself'));
|
|
181
181
|
|
|
182
182
|
if (!confirmationResult) return;
|
|
183
183
|
|
|
184
184
|
const { options, error } = await requestPasskeyChallenge(confirmationResult);
|
|
185
185
|
if (!options) {
|
|
186
|
-
adminforth.alert({ message: error ?? 'Verification failed.', variant: 'warning' });
|
|
186
|
+
adminforth.alert({ message: error ?? t('Verification failed.'), variant: 'warning' });
|
|
187
187
|
return;
|
|
188
188
|
}
|
|
189
189
|
|
|
@@ -210,9 +210,9 @@
|
|
|
210
210
|
passkeys.value = response.data;
|
|
211
211
|
authenticatorAttachment.value = response.authenticatorAttachment;
|
|
212
212
|
} catch (error) {
|
|
213
|
-
console.error('Error fetching passkeys:', error);
|
|
213
|
+
console.error(t('Error fetching passkeys:'), error);
|
|
214
214
|
if (coreStore.adminUser?.username) {
|
|
215
|
-
adminforth.alert({ message: 'Error fetching passkeys.', variant: 'warning' });
|
|
215
|
+
adminforth.alert({ message: t('Error fetching passkeys.'), variant: 'warning' });
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
}
|
|
@@ -226,12 +226,12 @@
|
|
|
226
226
|
method: 'POST',
|
|
227
227
|
body: { mode: addPasskeyMode.value, confirmationResult },
|
|
228
228
|
});
|
|
229
|
-
if (!response.ok) return { error: response.error ?? 'Verification failed' };
|
|
229
|
+
if (!response.ok) return { error: response.error ?? t('Verification failed') };
|
|
230
230
|
const options = PublicKeyCredential.parseCreationOptionsFromJSON(response.data);
|
|
231
231
|
return { options, challengeId: response.challengeId };
|
|
232
232
|
} catch (error) {
|
|
233
|
-
console.error('Error requesting passkey challenge:', error);
|
|
234
|
-
return { error: 'Failed to request passkey challenge' };
|
|
233
|
+
console.error(t('Error requesting passkey challenge:', error));
|
|
234
|
+
return { error: t('Failed to request passkey challenge' )};
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
237
|
|
|
@@ -240,8 +240,8 @@
|
|
|
240
240
|
const credential = await navigator.credentials.create({ publicKey: options });
|
|
241
241
|
return JSON.stringify((credential as PublicKeyCredential).toJSON());
|
|
242
242
|
} catch (error) {
|
|
243
|
-
console.error('Error creating WebAuthn credential:', error);
|
|
244
|
-
adminforth.alert({ message: 'Error creating passkey.', variant: 'warning' });
|
|
243
|
+
console.error(t('Error creating WebAuthn credential:', error));
|
|
244
|
+
adminforth.alert({ message: t('Error creating passkey.'), variant: 'warning' });
|
|
245
245
|
return null;
|
|
246
246
|
}
|
|
247
247
|
}
|
|
@@ -254,13 +254,13 @@
|
|
|
254
254
|
body: { credential, origin: window.location.origin },
|
|
255
255
|
});
|
|
256
256
|
if (res.ok) {
|
|
257
|
-
adminforth.alert({ message: 'Passkey registered successfully!', variant: 'success' });
|
|
257
|
+
adminforth.alert({ message: t('Passkey registered successfully!'), variant: 'success' });
|
|
258
258
|
getPasskeys();
|
|
259
259
|
} else {
|
|
260
|
-
adminforth.alert({ message: 'Error registering passkey.', variant: 'warning' });
|
|
260
|
+
adminforth.alert({ message: t('Error registering passkey.'), variant: 'warning' });
|
|
261
261
|
}
|
|
262
262
|
} catch (error) {
|
|
263
|
-
console.error('Error registering passkey:', error);
|
|
263
|
+
console.error(t('Error registering passkey:', error));
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
266
|
|
|
@@ -283,15 +283,15 @@
|
|
|
283
283
|
body: { passkeyId },
|
|
284
284
|
});
|
|
285
285
|
if (response.ok) {
|
|
286
|
-
adminforth.alert({ message: 'Passkey deleted successfully!', variant: 'success' });
|
|
286
|
+
adminforth.alert({ message: t('Passkey deleted successfully!'), variant: 'success' });
|
|
287
287
|
getPasskeys();
|
|
288
288
|
} else {
|
|
289
|
-
console.error('Error deleting passkey:', response?.error);
|
|
290
|
-
adminforth.alert({ message: 'Error deleting passkey.', variant: 'warning' });
|
|
289
|
+
console.error(t('Error deleting passkey:', response?.error));
|
|
290
|
+
adminforth.alert({ message: t('Error deleting passkey.'), variant: 'warning' });
|
|
291
291
|
}
|
|
292
292
|
} catch (error) {
|
|
293
|
-
console.error('Error deleting passkey:', error);
|
|
294
|
-
adminforth.alert({ message: 'Error deleting passkey.', variant: 'warning' });
|
|
293
|
+
console.error(t('Error deleting passkey:', error));
|
|
294
|
+
adminforth.alert({ message: t('Error deleting passkey.'), variant: 'warning' });
|
|
295
295
|
}
|
|
296
296
|
}
|
|
297
297
|
|
|
@@ -303,15 +303,15 @@
|
|
|
303
303
|
body: { passkeyId, newName: name },
|
|
304
304
|
});
|
|
305
305
|
if (response.ok) {
|
|
306
|
-
adminforth.alert({ message: 'Passkey updated successfully!', variant: 'success' });
|
|
306
|
+
adminforth.alert({ message: t('Passkey updated successfully!'), variant: 'success' });
|
|
307
307
|
getPasskeys();
|
|
308
308
|
} else {
|
|
309
|
-
console.error('Error updating passkey:', response.error);
|
|
310
|
-
adminforth.alert({ message: 'Error updating passkey.', variant: 'warning' });
|
|
309
|
+
console.error(t('Error updating passkey:', response.error));
|
|
310
|
+
adminforth.alert({ message: t('Error updating passkey.'), variant: 'warning' });
|
|
311
311
|
}
|
|
312
312
|
} catch (error) {
|
|
313
|
-
console.error('Error updating passkey:', error);
|
|
314
|
-
adminforth.alert({ message: 'Error updating passkey.', variant: 'warning' });
|
|
313
|
+
console.error(t('Error updating passkey:', error));
|
|
314
|
+
adminforth.alert({ message: t('Error updating passkey.'), variant: 'warning' });
|
|
315
315
|
}
|
|
316
316
|
}
|
|
317
317
|
|