mbkauthe 4.0.0 → 4.0.1
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/index.js +4 -1
- package/package.json +1 -1
- package/views/Error/dError.handlebars +175 -88
package/index.js
CHANGED
|
@@ -95,5 +95,8 @@ export {
|
|
|
95
95
|
} from "./lib/middleware/auth.js";
|
|
96
96
|
export { renderError } from "./lib/utils/response.js";
|
|
97
97
|
export { dblogin } from "./lib/database/pool.js";
|
|
98
|
-
export {
|
|
98
|
+
export {
|
|
99
|
+
ErrorCodes, ErrorMessages, getErrorByCode,
|
|
100
|
+
createErrorResponse, logError
|
|
101
|
+
} from "./lib/utils/errors.js";
|
|
99
102
|
export default router;
|
package/package.json
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
{{> head pageCode=code pageError=error ogUrl="/error" extraStyles="<style>
|
|
5
5
|
.login-box {
|
|
6
6
|
max-width: 600px;
|
|
7
|
+
padding: 2.5rem;
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
.status-code {
|
|
@@ -35,7 +36,6 @@
|
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
.status-content {
|
|
38
|
-
margin-bottom: 1.5rem;
|
|
39
39
|
text-align: center;
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -43,12 +43,12 @@
|
|
|
43
43
|
font-size: 1.2rem;
|
|
44
44
|
margin: 0.5rem 0;
|
|
45
45
|
color: var(--warning);
|
|
46
|
+
line-height: 1.4;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
.status-links {
|
|
49
50
|
display: flex;
|
|
50
51
|
justify-content: center;
|
|
51
|
-
margin-top: 1rem;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
.status-link {
|
|
@@ -57,90 +57,146 @@
|
|
|
57
57
|
transition: var(--transition);
|
|
58
58
|
margin: 0 auto;
|
|
59
59
|
font-size: 1rem;
|
|
60
|
-
font-weight:
|
|
60
|
+
font-weight: 700;
|
|
61
|
+
padding: 0.5rem 0.75rem;
|
|
62
|
+
border-radius: var(--border-radius);
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
.status-link:hover {
|
|
64
|
-
text-decoration:
|
|
66
|
+
text-decoration: none;
|
|
67
|
+
background: rgba(255,255,255,0.02);
|
|
65
68
|
color: var(--secondary);
|
|
69
|
+
transform: translateY(-2px);
|
|
66
70
|
}
|
|
67
71
|
|
|
72
|
+
/* Details wrapper: improved layout, accessibility and animation */
|
|
68
73
|
.details-wrapper {
|
|
69
|
-
margin-top: 1.
|
|
70
|
-
background: rgba(255, 255, 255, .
|
|
74
|
+
margin-top: 1.25rem;
|
|
75
|
+
background: rgba(255, 255, 255, .03);
|
|
71
76
|
border-radius: var(--border-radius);
|
|
72
|
-
padding:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
border: 1px solid rgba(255, 255, 255, .1);
|
|
77
|
+
padding: 0;
|
|
78
|
+
transition: box-shadow .25s ease, transform .25s ease;
|
|
79
|
+
border: 1px solid rgba(255, 255, 255, .06);
|
|
80
|
+
overflow: visible;
|
|
77
81
|
}
|
|
78
82
|
|
|
79
|
-
.details-
|
|
80
|
-
background: rgba(255, 255, 255, .08);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
.details-header {
|
|
83
|
+
.details-toggle {
|
|
84
84
|
display: flex;
|
|
85
|
-
justify-content: space-between;
|
|
86
85
|
align-items: center;
|
|
86
|
+
justify-content: space-between;
|
|
87
|
+
width: 100%;
|
|
88
|
+
background: transparent;
|
|
89
|
+
border: 0;
|
|
87
90
|
color: var(--light);
|
|
88
|
-
font-size: 1.
|
|
91
|
+
font-size: 1.05rem;
|
|
89
92
|
font-weight: 600;
|
|
93
|
+
padding: 0.85rem 1rem;
|
|
94
|
+
cursor: pointer;
|
|
90
95
|
}
|
|
91
96
|
|
|
92
|
-
.details-
|
|
93
|
-
|
|
97
|
+
.details-toggle:focus {
|
|
98
|
+
outline: 3px solid rgba(100, 150, 255, .18);
|
|
99
|
+
outline-offset: 2px;
|
|
100
|
+
border-radius: var(--border-radius);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.details-toggle .chev {
|
|
104
|
+
transition: transform .25s ease, color .2s ease;
|
|
105
|
+
color: var(--muted);
|
|
94
106
|
}
|
|
95
107
|
|
|
96
|
-
.details-wrapper:hover .details-
|
|
108
|
+
.details-wrapper:hover .details-toggle .chev {
|
|
97
109
|
color: var(--accent);
|
|
98
110
|
}
|
|
99
111
|
|
|
100
112
|
.error-details-wrapper {
|
|
101
|
-
|
|
102
|
-
|
|
113
|
+
max-height: 0;
|
|
114
|
+
overflow: hidden;
|
|
115
|
+
opacity: 0;
|
|
116
|
+
transition: max-height .33s cubic-bezier(.2,.9,.2,1), opacity .25s ease;
|
|
117
|
+
padding: 0 1rem;
|
|
103
118
|
}
|
|
104
119
|
|
|
105
120
|
.details-wrapper.active .error-details-wrapper {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
.details-wrapper.active .details-header i {
|
|
110
|
-
transform: rotate(180deg);
|
|
121
|
+
max-height: 480px; /* large enough for content */
|
|
122
|
+
opacity: 1;
|
|
123
|
+
padding: 0.9rem 1rem 1.25rem 1rem;
|
|
111
124
|
}
|
|
112
125
|
|
|
113
126
|
.error-details {
|
|
114
127
|
width: 100%;
|
|
115
|
-
height:
|
|
116
|
-
background: rgba(0, 0, 0, .
|
|
117
|
-
border: 1px solid rgba(255, 255, 255, .
|
|
118
|
-
border-radius: var(--border-radius);
|
|
128
|
+
min-height: 140px;
|
|
129
|
+
background: rgba(0, 0, 0, .28);
|
|
130
|
+
border: 1px solid rgba(255, 255, 255, .08);
|
|
131
|
+
border-radius: calc(var(--border-radius) - 2px);
|
|
119
132
|
color: var(--text);
|
|
120
|
-
padding:
|
|
121
|
-
|
|
133
|
+
padding: 0.9rem;
|
|
134
|
+
padding-right: 3.6rem; /* leave space for overlay button */
|
|
135
|
+
box-sizing: border-box;
|
|
136
|
+
resize: vertical;
|
|
122
137
|
font-size: 0.9rem;
|
|
123
|
-
font-family: monospace;
|
|
138
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, 'Roboto Mono', monospace;
|
|
139
|
+
line-height: 1.45;
|
|
124
140
|
}
|
|
125
141
|
|
|
142
|
+
.error-details-container {
|
|
143
|
+
position: relative;
|
|
144
|
+
width: 100%;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* Overlay copy button positioned inside the details container */
|
|
126
148
|
.copy-btn {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
149
|
+
position: absolute;
|
|
150
|
+
top: 0.6rem;
|
|
151
|
+
right: 0.65rem;
|
|
152
|
+
background: rgba(0,0,0,0.55);
|
|
153
|
+
color: var(--text);
|
|
154
|
+
border: 1px solid rgba(255,255,255,0.06);
|
|
155
|
+
border-radius: 6px;
|
|
156
|
+
padding: 0.45rem 0.6rem;
|
|
133
157
|
cursor: pointer;
|
|
134
|
-
transition:
|
|
135
|
-
font-size:
|
|
136
|
-
font-weight:
|
|
137
|
-
box-shadow:
|
|
158
|
+
transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
|
|
159
|
+
font-size: 0.95rem;
|
|
160
|
+
font-weight: 700;
|
|
161
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.18);
|
|
162
|
+
display: inline-flex;
|
|
163
|
+
gap: 0.45rem;
|
|
164
|
+
align-items: center;
|
|
165
|
+
z-index: 6;
|
|
166
|
+
backdrop-filter: blur(4px);
|
|
138
167
|
}
|
|
139
168
|
|
|
140
169
|
.copy-btn:hover {
|
|
141
|
-
background: var(--
|
|
170
|
+
background: var(--accent);
|
|
171
|
+
color: var(--dark);
|
|
142
172
|
transform: translateY(-2px);
|
|
143
|
-
box-shadow: 0
|
|
173
|
+
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.28);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.copy-feedback {
|
|
177
|
+
position: absolute;
|
|
178
|
+
top: 2.4rem;
|
|
179
|
+
right: 0.6rem;
|
|
180
|
+
background: rgba(0,0,0,0.65);
|
|
181
|
+
color: var(--accent);
|
|
182
|
+
padding: 0.25rem 0.5rem;
|
|
183
|
+
font-weight: 700;
|
|
184
|
+
border-radius: 4px;
|
|
185
|
+
font-size: 0.85rem;
|
|
186
|
+
display: none;
|
|
187
|
+
z-index: 6;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.sr-only {
|
|
191
|
+
position: absolute !important;
|
|
192
|
+
width: 1px !important;
|
|
193
|
+
height: 1px !important;
|
|
194
|
+
padding: 0 !important;
|
|
195
|
+
margin: -1px !important;
|
|
196
|
+
overflow: hidden !important;
|
|
197
|
+
clip: rect(0, 0, 0, 0) !important;
|
|
198
|
+
white-space: nowrap !important;
|
|
199
|
+
border: 0 !important;
|
|
144
200
|
}
|
|
145
201
|
|
|
146
202
|
@media (max-width: 768px) {
|
|
@@ -149,8 +205,10 @@
|
|
|
149
205
|
}
|
|
150
206
|
|
|
151
207
|
.status-title {
|
|
152
|
-
font-size: 1.
|
|
208
|
+
font-size: 1.25rem;
|
|
153
209
|
}
|
|
210
|
+
|
|
211
|
+
.login-box { padding: 1.5rem; }
|
|
154
212
|
}
|
|
155
213
|
|
|
156
214
|
@media (max-width: 576px) {
|
|
@@ -186,17 +244,19 @@
|
|
|
186
244
|
</div>
|
|
187
245
|
|
|
188
246
|
{{#if details}}
|
|
189
|
-
<div class="details-wrapper"
|
|
190
|
-
<
|
|
191
|
-
<span>Show
|
|
192
|
-
<i class="fas fa-chevron-down"></i>
|
|
193
|
-
</
|
|
194
|
-
<div class="error-details-wrapper">
|
|
195
|
-
<
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
247
|
+
<div class="details-wrapper">
|
|
248
|
+
<button class="details-toggle" type="button" aria-expanded="false" aria-controls="errorDetails">
|
|
249
|
+
<span>Show error details</span>
|
|
250
|
+
<i class="fas fa-chevron-down chev" aria-hidden="true"></i>
|
|
251
|
+
</button>
|
|
252
|
+
<div class="error-details-wrapper" id="errorDetails" hidden>
|
|
253
|
+
<div class="error-details-container">
|
|
254
|
+
<textarea class="error-details" readonly>{{details}}</textarea>
|
|
255
|
+
<button class="copy-btn" type="button" aria-label="Copy error details">
|
|
256
|
+
<i class="fas fa-copy" aria-hidden="true"></i><span class="sr-only"> Copy</span>
|
|
257
|
+
</button>
|
|
258
|
+
<span class="copy-feedback" aria-live="polite">Copied!</span>
|
|
259
|
+
</div>
|
|
200
260
|
</div>
|
|
201
261
|
</div>
|
|
202
262
|
{{/if}}
|
|
@@ -207,36 +267,63 @@
|
|
|
207
267
|
{{> versionInfo}}
|
|
208
268
|
|
|
209
269
|
<script>
|
|
210
|
-
function toggleDetailsDropdown(element) {
|
|
211
|
-
const errorDetailsWrapper = element.querySelector('.error-details-wrapper');
|
|
212
|
-
const icon = element.querySelector('.details-header i');
|
|
213
|
-
|
|
214
|
-
if (errorDetailsWrapper.style.display === 'block') {
|
|
215
|
-
errorDetailsWrapper.style.display = 'none';
|
|
216
|
-
icon.style.transform = 'rotate(0deg)';
|
|
217
|
-
} else {
|
|
218
|
-
errorDetailsWrapper.style.display = 'block';
|
|
219
|
-
icon.style.transform = 'rotate(180deg)';
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
function copyErrorDetails(button) {
|
|
224
|
-
const details = button.previousElementSibling.value;
|
|
225
|
-
navigator.clipboard.writeText(details).then(() => {
|
|
226
|
-
button.textContent = 'Copied!';
|
|
227
|
-
setTimeout(() => {
|
|
228
|
-
button.textContent = 'Copy';
|
|
229
|
-
}, 2000);
|
|
230
|
-
}).catch(err => {
|
|
231
|
-
console.error('[mbkauthe] Failed to copy: ', err);
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
|
|
235
270
|
document.addEventListener('DOMContentLoaded', () => {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
wrapper.
|
|
239
|
-
|
|
271
|
+
document.querySelectorAll('.details-wrapper').forEach(wrapper => {
|
|
272
|
+
const toggle = wrapper.querySelector('.details-toggle');
|
|
273
|
+
const details = wrapper.querySelector('.error-details-wrapper');
|
|
274
|
+
const icon = wrapper.querySelector('.chev');
|
|
275
|
+
const copyBtn = wrapper.querySelector('.copy-btn');
|
|
276
|
+
const feedback = wrapper.querySelector('.copy-feedback');
|
|
277
|
+
|
|
278
|
+
if (!toggle || !details) return;
|
|
279
|
+
|
|
280
|
+
// initialize hidden state and maxHeight for animation
|
|
281
|
+
details.style.maxHeight = details.hidden ? '0px' : details.scrollHeight + 'px';
|
|
282
|
+
|
|
283
|
+
toggle.addEventListener('click', (e) => {
|
|
284
|
+
e.stopPropagation();
|
|
285
|
+
const isOpen = wrapper.classList.toggle('active');
|
|
286
|
+
toggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
|
|
287
|
+
details.hidden = !isOpen;
|
|
288
|
+
|
|
289
|
+
if (isOpen) {
|
|
290
|
+
details.style.maxHeight = details.scrollHeight + 'px';
|
|
291
|
+
if (icon) icon.style.transform = 'rotate(180deg)';
|
|
292
|
+
} else {
|
|
293
|
+
details.style.maxHeight = '0px';
|
|
294
|
+
if (icon) icon.style.transform = 'rotate(0deg)';
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
if (copyBtn) {
|
|
299
|
+
copyBtn.addEventListener('click', async (e) => {
|
|
300
|
+
e.stopPropagation();
|
|
301
|
+
const textarea = wrapper.querySelector('.error-details');
|
|
302
|
+
try {
|
|
303
|
+
await navigator.clipboard.writeText(textarea.value);
|
|
304
|
+
if (feedback) {
|
|
305
|
+
feedback.style.display = 'inline';
|
|
306
|
+
setTimeout(() => { feedback.style.display = 'none'; }, 2000);
|
|
307
|
+
} else {
|
|
308
|
+
const orig = copyBtn.innerHTML;
|
|
309
|
+
copyBtn.innerHTML = '<i class="fas fa-check" aria-hidden="true"></i> Copied';
|
|
310
|
+
setTimeout(() => { copyBtn.innerHTML = orig; }, 2000);
|
|
311
|
+
}
|
|
312
|
+
} catch (err) {
|
|
313
|
+
console.error('[mbkauthe] Failed to copy: ', err);
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// close the details when user clicks outside
|
|
319
|
+
document.addEventListener('click', (e) => {
|
|
320
|
+
if (!wrapper.contains(e.target) && wrapper.classList.contains('active')) {
|
|
321
|
+
wrapper.classList.remove('active');
|
|
322
|
+
toggle.setAttribute('aria-expanded', 'false');
|
|
323
|
+
details.hidden = true;
|
|
324
|
+
if (icon) icon.style.transform = 'rotate(0deg)';
|
|
325
|
+
details.style.maxHeight = '0px';
|
|
326
|
+
}
|
|
240
327
|
});
|
|
241
328
|
});
|
|
242
329
|
});
|