-
Notifications
You must be signed in to change notification settings - Fork 272
Expand file tree
/
Copy pathManagePasskeys.cshtml
More file actions
117 lines (107 loc) · 4.98 KB
/
Copy pathManagePasskeys.cshtml
File metadata and controls
117 lines (107 loc) · 4.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
@page
@model UserManagementSample.Pages.Manage.ManagePasskeysModel
@{
ViewData["Title"] = "Manage Passkeys";
}
<div class="row justify-content-center">
<div class="col-md-8 col-lg-7">
<div class="form-container">
<h2 class="mb-4 brand-title text-center">Manage Passkeys</h2>
@if (Model.ErrorMessages.Count > 0)
{
<div class="alert alert-danger" role="alert">
@foreach (var error in Model.ErrorMessages)
{
<div><i class="bi bi-exclamation-triangle-fill me-2"></i>@error</div>
}
</div>
}
@if (!string.IsNullOrEmpty(Model.SuccessMessage))
{
<div class="alert alert-success" role="alert">
<i class="bi bi-check-circle-fill me-2"></i>@Model.SuccessMessage
</div>
}
<div id="passkey-status" class="alert d-none" role="alert"></div>
@if (Model.Passkeys.Any())
{
<div class="table-responsive mb-4">
<table class="table table-hover align-middle">
<thead>
<tr>
<th>Name</th>
<th>Created</th>
<th class="text-end"></th>
</tr>
</thead>
<tbody>
@foreach (var passkey in Model.Passkeys)
{
<tr>
<td>
<i class="bi bi-fingerprint me-2 text-primary"></i>@passkey.Name
</td>
<td>@passkey.CreatedAt.ToString("u")</td>
<td class="text-end">
<form method="post" asp-page-handler="RemovePasskey" class="d-inline">
<input type="hidden" name="credentialId" value="@passkey.CredentialId.ToBase64String()" />
<button type="submit" class="btn btn-sm btn-outline-danger"
onclick="return confirm('Are you sure you want to remove this passkey?');">
<i class="bi bi-trash"></i> Remove
</button>
</form>
</td>
</tr>
}
</tbody>
</table>
</div>
}
else
{
<p class="text-muted mb-4">You have no registered passkeys. Add one below to sign in securely without a password.</p>
}
<div class="d-grid gap-2">
<div class="input-group mb-2">
<input type="text" id="passkey-name" class="form-control" placeholder="Passkey name (e.g. Work Laptop)" />
<button type="button" id="add-passkey-btn" class="btn btn-primary">
<i class="bi bi-plus-circle me-2"></i>Add Passkey
</button>
</div>
<a asp-page="/Index" class="btn btn-outline-secondary">
<i class="bi bi-arrow-left me-2"></i>Back
</a>
</div>
</div>
</div>
</div>
@section Scripts {
<script src="/passkeys/js"></script>
<script>
(function () {
const statusBox = document.getElementById('passkey-status');
function showStatus(message, isError) {
statusBox.textContent = message;
statusBox.className = 'alert ' + (isError ? 'alert-danger' : 'alert-success');
statusBox.classList.remove('d-none');
}
document.getElementById('add-passkey-btn').addEventListener('click', async function () {
const btn = this;
const nameInput = document.getElementById('passkey-name');
const displayName = nameInput.value.trim() || '@Model.DisplayName';
btn.disabled = true;
statusBox.classList.add('d-none');
try {
const result = await registerPasskey(displayName, displayName);
console.log('Passkey registration result:', result);
showStatus('Passkey registered successfully!', false);
setTimeout(() => window.location.reload(), 1000);
} catch (err) {
console.error('Passkey registration error:', err);
showStatus(err?.message ?? 'Passkey registration failed. Please try again.', true);
btn.disabled = false;
}
});
})();
</script>
}