@jskit-ai/auth-web 0.1.147 → 0.1.149
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/auth-web",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.149",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
"./test/playwright": "./src/test/playwright.js"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@jskit-ai/auth-core": "0.1.
|
|
24
|
-
"@
|
|
25
|
-
"@jskit-ai/kernel": "0.1.
|
|
26
|
-
"@jskit-ai/shell-web": "0.1.
|
|
27
|
-
"@
|
|
23
|
+
"@jskit-ai/auth-core": "0.1.147",
|
|
24
|
+
"@jskit-ai/http-runtime": "0.1.147",
|
|
25
|
+
"@jskit-ai/kernel": "0.1.149",
|
|
26
|
+
"@jskit-ai/shell-web": "0.1.153",
|
|
27
|
+
"@mdi/js": "^7.4.47"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"@tanstack/vue-query": "^5.90.5",
|
|
@@ -32,5 +32,371 @@
|
|
|
32
32
|
"vue": "^3.5.13",
|
|
33
33
|
"vue-router": "^5.0.4",
|
|
34
34
|
"vuetify": "^4.0.0"
|
|
35
|
+
},
|
|
36
|
+
"description": "Auth web module: Fastify auth routes plus web login/sign-out scaffolds.",
|
|
37
|
+
"jskit": {
|
|
38
|
+
"kind": "runtime",
|
|
39
|
+
"capabilities": {
|
|
40
|
+
"provides": [
|
|
41
|
+
"auth.server-routes",
|
|
42
|
+
"auth.web-login"
|
|
43
|
+
],
|
|
44
|
+
"requires": [
|
|
45
|
+
"auth.access",
|
|
46
|
+
"auth.provider",
|
|
47
|
+
"validators.http",
|
|
48
|
+
"auth.policy",
|
|
49
|
+
"runtime.web-placement"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"runtime": {
|
|
53
|
+
"server": {
|
|
54
|
+
"providerEntrypoint": "src/server/providers/AuthWebServiceProvider.js",
|
|
55
|
+
"providers": [
|
|
56
|
+
{
|
|
57
|
+
"entrypoint": "src/server/providers/AuthWebServiceProvider.js",
|
|
58
|
+
"export": "AuthWebServiceProvider"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"entrypoint": "src/server/providers/AuthRouteServiceProvider.js",
|
|
62
|
+
"export": "AuthRouteServiceProvider"
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
"client": {
|
|
67
|
+
"providers": [
|
|
68
|
+
{
|
|
69
|
+
"entrypoint": "src/client/providers/AuthWebClientProvider.js",
|
|
70
|
+
"export": "AuthWebClientProvider"
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"metadata": {
|
|
76
|
+
"apiSummary": {
|
|
77
|
+
"surfaces": [
|
|
78
|
+
{
|
|
79
|
+
"subpath": "./client",
|
|
80
|
+
"summary": "Exports auth web client provider, default auth views, and route/provider registration surface."
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"subpath": "./server",
|
|
84
|
+
"summary": "Exports auth web server providers, controller/service classes, route builders, and HTTP schema modules."
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"subpath": "./test/playwright",
|
|
88
|
+
"summary": "Exports the localhost-only Playwright helper for creating a dev-auth session in the tested browser context."
|
|
89
|
+
}
|
|
90
|
+
],
|
|
91
|
+
"containerTokens": {
|
|
92
|
+
"server": [
|
|
93
|
+
"auth.web.service"
|
|
94
|
+
],
|
|
95
|
+
"client": [
|
|
96
|
+
"runtime.auth-guard.client",
|
|
97
|
+
"auth.login.component",
|
|
98
|
+
"auth.login.useLoginView",
|
|
99
|
+
"auth.web.profile.widget",
|
|
100
|
+
"auth.web.profile.menu.link-item"
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"server": {
|
|
105
|
+
"routes": [
|
|
106
|
+
{
|
|
107
|
+
"method": "POST",
|
|
108
|
+
"path": "/api/login",
|
|
109
|
+
"summary": "Log in with configured credentials"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"method": "POST",
|
|
113
|
+
"path": "/api/login/otp/request",
|
|
114
|
+
"summary": "Request one-time email login code"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"method": "POST",
|
|
118
|
+
"path": "/api/login/otp/verify",
|
|
119
|
+
"summary": "Verify one-time email login code and create session"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"method": "POST",
|
|
123
|
+
"path": "/api/logout",
|
|
124
|
+
"summary": "Log out and clear session cookies"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"method": "GET",
|
|
128
|
+
"path": "/api/oauth/:provider/start",
|
|
129
|
+
"summary": "Start OAuth login with configured provider"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"method": "POST",
|
|
133
|
+
"path": "/api/oauth/complete",
|
|
134
|
+
"summary": "Complete OAuth code exchange and set session cookies"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"method": "POST",
|
|
138
|
+
"path": "/api/password/forgot",
|
|
139
|
+
"summary": "Request a password reset email"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"method": "POST",
|
|
143
|
+
"path": "/api/password/recovery",
|
|
144
|
+
"summary": "Complete password recovery link exchange"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"method": "POST",
|
|
148
|
+
"path": "/api/password/reset",
|
|
149
|
+
"summary": "Set a new password for authenticated recovery session"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"method": "POST",
|
|
153
|
+
"path": "/api/register",
|
|
154
|
+
"summary": "Register a new user"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"method": "GET",
|
|
158
|
+
"path": "/api/session",
|
|
159
|
+
"summary": "Get current session status and CSRF token"
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
},
|
|
163
|
+
"ui": {
|
|
164
|
+
"routes": [
|
|
165
|
+
{
|
|
166
|
+
"id": "auth.login",
|
|
167
|
+
"path": "/auth/login",
|
|
168
|
+
"scope": "surface",
|
|
169
|
+
"surface": "auth",
|
|
170
|
+
"name": "auth-login",
|
|
171
|
+
"componentKey": "auth-login",
|
|
172
|
+
"autoRegister": false,
|
|
173
|
+
"guard": {
|
|
174
|
+
"policy": "public"
|
|
175
|
+
},
|
|
176
|
+
"purpose": "Public login route for authentication flows."
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"id": "auth.signout",
|
|
180
|
+
"path": "/auth/signout",
|
|
181
|
+
"scope": "surface",
|
|
182
|
+
"surface": "auth",
|
|
183
|
+
"name": "auth-signout",
|
|
184
|
+
"componentKey": "auth-signout",
|
|
185
|
+
"autoRegister": false,
|
|
186
|
+
"guard": {
|
|
187
|
+
"policy": "public"
|
|
188
|
+
},
|
|
189
|
+
"purpose": "Public sign-out route that clears session then returns to login."
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"id": "auth.reset-password",
|
|
193
|
+
"path": "/auth/reset-password",
|
|
194
|
+
"scope": "surface",
|
|
195
|
+
"surface": "auth",
|
|
196
|
+
"name": "auth-reset-password",
|
|
197
|
+
"componentKey": "auth-reset-password",
|
|
198
|
+
"autoRegister": false,
|
|
199
|
+
"guard": {
|
|
200
|
+
"policy": "public"
|
|
201
|
+
},
|
|
202
|
+
"purpose": "Public password reset screen for recovery links."
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"id": "auth.default-login",
|
|
206
|
+
"path": "/auth/default-login",
|
|
207
|
+
"scope": "surface",
|
|
208
|
+
"surface": "auth",
|
|
209
|
+
"name": "auth-default-login",
|
|
210
|
+
"componentKey": "auth-default-login",
|
|
211
|
+
"autoRegister": true,
|
|
212
|
+
"guard": {
|
|
213
|
+
"policy": "public"
|
|
214
|
+
},
|
|
215
|
+
"purpose": "Default module-supplied login screen."
|
|
216
|
+
}
|
|
217
|
+
],
|
|
218
|
+
"elements": [],
|
|
219
|
+
"overrides": [],
|
|
220
|
+
"placements": {
|
|
221
|
+
"outlets": [
|
|
222
|
+
{
|
|
223
|
+
"target": "auth-profile-menu:primary-menu",
|
|
224
|
+
"surfaces": [
|
|
225
|
+
"*"
|
|
226
|
+
],
|
|
227
|
+
"source": "src/client/views/AuthProfileWidget.vue"
|
|
228
|
+
}
|
|
229
|
+
],
|
|
230
|
+
"topology": {
|
|
231
|
+
"placements": [
|
|
232
|
+
{
|
|
233
|
+
"id": "auth.profile-menu",
|
|
234
|
+
"description": "Authenticated profile menu actions.",
|
|
235
|
+
"surfaces": [
|
|
236
|
+
"*"
|
|
237
|
+
],
|
|
238
|
+
"variants": {
|
|
239
|
+
"compact": {
|
|
240
|
+
"outlet": "auth-profile-menu:primary-menu",
|
|
241
|
+
"renderers": {
|
|
242
|
+
"link": "auth.web.profile.menu.link-item"
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
"medium": {
|
|
246
|
+
"outlet": "auth-profile-menu:primary-menu",
|
|
247
|
+
"renderers": {
|
|
248
|
+
"link": "auth.web.profile.menu.link-item"
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
"expanded": {
|
|
252
|
+
"outlet": "auth-profile-menu:primary-menu",
|
|
253
|
+
"renderers": {
|
|
254
|
+
"link": "auth.web.profile.menu.link-item"
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
]
|
|
260
|
+
},
|
|
261
|
+
"contributions": [
|
|
262
|
+
{
|
|
263
|
+
"id": "auth.profile.widget",
|
|
264
|
+
"target": "shell.status",
|
|
265
|
+
"kind": "component",
|
|
266
|
+
"surfaces": [
|
|
267
|
+
"*"
|
|
268
|
+
],
|
|
269
|
+
"order": 1000,
|
|
270
|
+
"componentToken": "auth.web.profile.widget",
|
|
271
|
+
"source": "mutations.text#auth-web-placement-block"
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
"id": "auth.profile.menu.sign-in",
|
|
275
|
+
"target": "auth.profile-menu",
|
|
276
|
+
"kind": "link",
|
|
277
|
+
"surfaces": [
|
|
278
|
+
"*"
|
|
279
|
+
],
|
|
280
|
+
"order": 200,
|
|
281
|
+
"when": "auth.authenticated !== true",
|
|
282
|
+
"source": "mutations.text#auth-web-placement-block"
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"id": "auth.profile.menu.sign-out",
|
|
286
|
+
"target": "auth.profile-menu",
|
|
287
|
+
"kind": "link",
|
|
288
|
+
"surfaces": [
|
|
289
|
+
"*"
|
|
290
|
+
],
|
|
291
|
+
"order": 1000,
|
|
292
|
+
"when": "auth.authenticated === true",
|
|
293
|
+
"source": "mutations.text#auth-web-placement-block"
|
|
294
|
+
}
|
|
295
|
+
]
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
"mutations": {
|
|
300
|
+
"dependencies": {
|
|
301
|
+
"runtime": {
|
|
302
|
+
"@mdi/js": "^7.4.47",
|
|
303
|
+
"@jskit-ai/auth-core": "0.1.147",
|
|
304
|
+
"@jskit-ai/http-runtime": "0.1.147",
|
|
305
|
+
"@jskit-ai/kernel": "0.1.149",
|
|
306
|
+
"@jskit-ai/shell-web": "0.1.153"
|
|
307
|
+
},
|
|
308
|
+
"dev": {}
|
|
309
|
+
},
|
|
310
|
+
"packageJson": {
|
|
311
|
+
"scripts": {
|
|
312
|
+
"server:auth": "SERVER_SURFACE=auth node ./bin/server.js",
|
|
313
|
+
"dev:auth": "VITE_SURFACE=auth vite",
|
|
314
|
+
"build:auth": "VITE_SURFACE=auth vite build"
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
"procfile": {},
|
|
318
|
+
"files": [
|
|
319
|
+
{
|
|
320
|
+
"from": "templates/src/views/auth/LoginView.vue",
|
|
321
|
+
"to": "src/views/auth/LoginView.vue",
|
|
322
|
+
"ownership": "app",
|
|
323
|
+
"reason": "Install minimal login container that renders the module-provided DefaultLoginView by default.",
|
|
324
|
+
"category": "auth-web",
|
|
325
|
+
"id": "auth-view-login"
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
"from": "templates/src/views/auth/SignOutView.vue",
|
|
329
|
+
"to": "src/views/auth/SignOutView.vue",
|
|
330
|
+
"ownership": "app",
|
|
331
|
+
"reason": "Install minimal sign-out container that renders the module-provided SignOutView by default (edit the scaffolded file to customize).",
|
|
332
|
+
"category": "auth-web",
|
|
333
|
+
"id": "auth-view-signout"
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
"from": "templates/src/views/auth/ResetPasswordView.vue",
|
|
337
|
+
"to": "src/views/auth/ResetPasswordView.vue",
|
|
338
|
+
"ownership": "app",
|
|
339
|
+
"reason": "Install minimal password reset container that renders the module-provided DefaultResetPasswordView by default.",
|
|
340
|
+
"category": "auth-web",
|
|
341
|
+
"id": "auth-view-reset-password"
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
"from": "templates/src/pages/auth/login.vue",
|
|
345
|
+
"to": "src/pages/auth/login.vue",
|
|
346
|
+
"ownership": "app",
|
|
347
|
+
"reason": "Provide an auth-surface /auth/login wrapper that renders the package login view.",
|
|
348
|
+
"category": "auth-web",
|
|
349
|
+
"id": "auth-page-login"
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
"from": "templates/src/pages/auth/signout.vue",
|
|
353
|
+
"to": "src/pages/auth/signout.vue",
|
|
354
|
+
"ownership": "app",
|
|
355
|
+
"reason": "Provide an auth-surface /auth/signout wrapper that renders the package sign-out view.",
|
|
356
|
+
"category": "auth-web",
|
|
357
|
+
"id": "auth-page-signout"
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
"from": "templates/src/pages/auth/reset-password.vue",
|
|
361
|
+
"to": "src/pages/auth/reset-password.vue",
|
|
362
|
+
"ownership": "app",
|
|
363
|
+
"reason": "Provide an auth-surface /auth/reset-password wrapper that renders the package password reset view.",
|
|
364
|
+
"category": "auth-web",
|
|
365
|
+
"id": "auth-page-reset-password"
|
|
366
|
+
}
|
|
367
|
+
],
|
|
368
|
+
"text": [
|
|
369
|
+
{
|
|
370
|
+
"op": "append-text",
|
|
371
|
+
"file": "config/public.js",
|
|
372
|
+
"position": "bottom",
|
|
373
|
+
"skipIfContains": "config.surfaceDefinitions.auth = {",
|
|
374
|
+
"value": "\nconfig.surfaceDefinitions.auth = {\n id: \"auth\",\n label: \"Auth\",\n pagesRoot: \"auth\",\n enabled: true,\n requiresAuth: false,\n requiresWorkspace: false,\n origin: \"\"\n};\n",
|
|
375
|
+
"reason": "Register auth surface definition in public surface config.",
|
|
376
|
+
"category": "auth-web",
|
|
377
|
+
"id": "auth-web-surface-config-auth"
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
"op": "append-text",
|
|
381
|
+
"file": "src/placement.js",
|
|
382
|
+
"position": "bottom",
|
|
383
|
+
"skipIfContains": "id: \"auth.profile.widget\"",
|
|
384
|
+
"value": "\naddPlacement({\n id: \"auth.profile.widget\",\n target: \"shell.status\",\n kind: \"component\",\n surfaces: [\"*\"],\n order: 1000,\n componentToken: \"auth.web.profile.widget\"\n});\n\naddPlacement({\n id: \"auth.profile.menu.sign-in\",\n target: \"auth.profile-menu\",\n kind: \"link\",\n surfaces: [\"*\"],\n order: 200,\n props: {\n label: \"Sign in\",\n to: \"/auth/login\"\n },\n when: ({ auth }) => auth?.authenticated !== true\n});\n\naddPlacement({\n id: \"auth.profile.menu.sign-out\",\n target: \"auth.profile-menu\",\n kind: \"link\",\n surfaces: [\"*\"],\n order: 1000,\n props: {\n label: \"Sign out\",\n to: \"/auth/signout\"\n },\n when: ({ auth }) => auth?.authenticated === true\n});\n",
|
|
385
|
+
"reason": "Append auth profile placement entries into app-owned placement registry.",
|
|
386
|
+
"category": "auth-web",
|
|
387
|
+
"id": "auth-web-placement-block"
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
"op": "append-text",
|
|
391
|
+
"file": "src/placementTopology.js",
|
|
392
|
+
"position": "bottom",
|
|
393
|
+
"skipIfContains": "id: \"auth.profile-menu\"",
|
|
394
|
+
"value": "\naddPlacementTopology({\n id: \"auth.profile-menu\",\n description: \"Authenticated profile menu actions.\",\n surfaces: [\"*\"],\n variants: {\n compact: {\n outlet: \"auth-profile-menu:primary-menu\",\n renderers: {\n link: \"auth.web.profile.menu.link-item\"\n }\n },\n medium: {\n outlet: \"auth-profile-menu:primary-menu\",\n renderers: {\n link: \"auth.web.profile.menu.link-item\"\n }\n },\n expanded: {\n outlet: \"auth-profile-menu:primary-menu\",\n renderers: {\n link: \"auth.web.profile.menu.link-item\"\n }\n }\n }\n});\n",
|
|
395
|
+
"reason": "Append auth profile menu topology into the app-owned placement topology.",
|
|
396
|
+
"category": "auth-web",
|
|
397
|
+
"id": "auth-web-profile-menu-topology"
|
|
398
|
+
}
|
|
399
|
+
]
|
|
400
|
+
}
|
|
35
401
|
}
|
|
36
402
|
}
|
|
@@ -2,15 +2,17 @@ import assert from "node:assert/strict";
|
|
|
2
2
|
import { existsSync, readFileSync } from "node:fs";
|
|
3
3
|
import test from "node:test";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import
|
|
5
|
+
import packageJson from "../package.json" with { type: "json" };
|
|
6
|
+
|
|
7
|
+
const packageMetadata = packageJson.jskit;
|
|
6
8
|
import {
|
|
7
9
|
useSignOut as fromRuntimeUseSignOut,
|
|
8
10
|
createSignOutAction as fromRuntimeCreateSignOutAction,
|
|
9
11
|
performSignOutRequest as fromRuntimePerformSignOutRequest
|
|
10
12
|
} from "../src/client/runtime/useSignOut.js";
|
|
11
13
|
|
|
12
|
-
test("auth-web
|
|
13
|
-
const uiRoutes = Array.isArray(
|
|
14
|
+
test("auth-web packageMetadata declares auth surface ui routes", () => {
|
|
15
|
+
const uiRoutes = Array.isArray(packageMetadata?.metadata?.ui?.routes) ? packageMetadata.metadata.ui.routes : [];
|
|
14
16
|
const authRoutes = uiRoutes.filter((route) => String(route?.path || "").startsWith("/auth/"));
|
|
15
17
|
const resetRoute = authRoutes.find((route) => route.id === "auth.reset-password");
|
|
16
18
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import test from "node:test";
|
|
3
|
-
import
|
|
3
|
+
import packageJson from "../package.json" with { type: "json" };
|
|
4
|
+
|
|
5
|
+
const packageMetadata = packageJson.jskit;
|
|
4
6
|
|
|
5
7
|
test("auth-web leaves its editable view and route scaffolds app-owned", () => {
|
|
6
8
|
const expectedIds = [
|
|
@@ -13,7 +15,7 @@ test("auth-web leaves its editable view and route scaffolds app-owned", () => {
|
|
|
13
15
|
];
|
|
14
16
|
|
|
15
17
|
for (const id of expectedIds) {
|
|
16
|
-
const mutation =
|
|
18
|
+
const mutation = packageMetadata.mutations.files.find((entry) => entry.id === id);
|
|
17
19
|
assert.ok(mutation, `Missing auth-web scaffold mutation ${id}.`);
|
|
18
20
|
assert.equal(mutation.ownership, "app", `${id} must remain app-owned across package updates.`);
|
|
19
21
|
}
|
package/package.descriptor.mjs
DELETED
|
@@ -1,365 +0,0 @@
|
|
|
1
|
-
export default Object.freeze({
|
|
2
|
-
"packageVersion": 1,
|
|
3
|
-
"packageId": "@jskit-ai/auth-web",
|
|
4
|
-
"version": "0.1.147",
|
|
5
|
-
"kind": "runtime",
|
|
6
|
-
"description": "Auth web module: Fastify auth routes plus web login/sign-out scaffolds.",
|
|
7
|
-
"dependsOn": [
|
|
8
|
-
"@jskit-ai/auth-core",
|
|
9
|
-
"@jskit-ai/http-runtime",
|
|
10
|
-
"@jskit-ai/shell-web",
|
|
11
|
-
"@jskit-ai/value-app-config-shared"
|
|
12
|
-
],
|
|
13
|
-
"capabilities": {
|
|
14
|
-
"provides": [
|
|
15
|
-
"auth.server-routes",
|
|
16
|
-
"auth.web-login"
|
|
17
|
-
],
|
|
18
|
-
"requires": [
|
|
19
|
-
"auth.access",
|
|
20
|
-
"auth.provider",
|
|
21
|
-
"validators.http",
|
|
22
|
-
"auth.policy",
|
|
23
|
-
"runtime.web-placement"
|
|
24
|
-
]
|
|
25
|
-
},
|
|
26
|
-
"runtime": {
|
|
27
|
-
"server": {
|
|
28
|
-
"providerEntrypoint": "src/server/providers/AuthWebServiceProvider.js",
|
|
29
|
-
"providers": [
|
|
30
|
-
{
|
|
31
|
-
"entrypoint": "src/server/providers/AuthWebServiceProvider.js",
|
|
32
|
-
"export": "AuthWebServiceProvider"
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"entrypoint": "src/server/providers/AuthRouteServiceProvider.js",
|
|
36
|
-
"export": "AuthRouteServiceProvider"
|
|
37
|
-
}
|
|
38
|
-
]
|
|
39
|
-
},
|
|
40
|
-
"client": {
|
|
41
|
-
"providers": [
|
|
42
|
-
{
|
|
43
|
-
"entrypoint": "src/client/providers/AuthWebClientProvider.js",
|
|
44
|
-
"export": "AuthWebClientProvider"
|
|
45
|
-
}
|
|
46
|
-
]
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
"metadata": {
|
|
50
|
-
"apiSummary": {
|
|
51
|
-
"surfaces": [
|
|
52
|
-
{
|
|
53
|
-
"subpath": "./client",
|
|
54
|
-
"summary": "Exports auth web client provider, default auth views, and route/provider registration surface."
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
"subpath": "./server",
|
|
58
|
-
"summary": "Exports auth web server providers, controller/service classes, route builders, and HTTP schema modules."
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
"subpath": "./test/playwright",
|
|
62
|
-
"summary": "Exports the localhost-only Playwright helper for creating a dev-auth session in the tested browser context."
|
|
63
|
-
}
|
|
64
|
-
],
|
|
65
|
-
"containerTokens": {
|
|
66
|
-
"server": [
|
|
67
|
-
"auth.web.service"
|
|
68
|
-
],
|
|
69
|
-
"client": [
|
|
70
|
-
"runtime.auth-guard.client",
|
|
71
|
-
"auth.login.component",
|
|
72
|
-
"auth.login.useLoginView",
|
|
73
|
-
"auth.web.profile.widget",
|
|
74
|
-
"auth.web.profile.menu.link-item"
|
|
75
|
-
]
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
"server": {
|
|
79
|
-
"routes": [
|
|
80
|
-
{
|
|
81
|
-
"method": "POST",
|
|
82
|
-
"path": "/api/login",
|
|
83
|
-
"summary": "Log in with configured credentials"
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
"method": "POST",
|
|
87
|
-
"path": "/api/login/otp/request",
|
|
88
|
-
"summary": "Request one-time email login code"
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
"method": "POST",
|
|
92
|
-
"path": "/api/login/otp/verify",
|
|
93
|
-
"summary": "Verify one-time email login code and create session"
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
"method": "POST",
|
|
97
|
-
"path": "/api/logout",
|
|
98
|
-
"summary": "Log out and clear session cookies"
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
"method": "GET",
|
|
102
|
-
"path": "/api/oauth/:provider/start",
|
|
103
|
-
"summary": "Start OAuth login with configured provider"
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
"method": "POST",
|
|
107
|
-
"path": "/api/oauth/complete",
|
|
108
|
-
"summary": "Complete OAuth code exchange and set session cookies"
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
"method": "POST",
|
|
112
|
-
"path": "/api/password/forgot",
|
|
113
|
-
"summary": "Request a password reset email"
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
"method": "POST",
|
|
117
|
-
"path": "/api/password/recovery",
|
|
118
|
-
"summary": "Complete password recovery link exchange"
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
"method": "POST",
|
|
122
|
-
"path": "/api/password/reset",
|
|
123
|
-
"summary": "Set a new password for authenticated recovery session"
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
"method": "POST",
|
|
127
|
-
"path": "/api/register",
|
|
128
|
-
"summary": "Register a new user"
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
"method": "GET",
|
|
132
|
-
"path": "/api/session",
|
|
133
|
-
"summary": "Get current session status and CSRF token"
|
|
134
|
-
}
|
|
135
|
-
]
|
|
136
|
-
},
|
|
137
|
-
"ui": {
|
|
138
|
-
"routes": [
|
|
139
|
-
{
|
|
140
|
-
"id": "auth.login",
|
|
141
|
-
"path": "/auth/login",
|
|
142
|
-
"scope": "surface",
|
|
143
|
-
"surface": "auth",
|
|
144
|
-
"name": "auth-login",
|
|
145
|
-
"componentKey": "auth-login",
|
|
146
|
-
"autoRegister": false,
|
|
147
|
-
"guard": {
|
|
148
|
-
"policy": "public"
|
|
149
|
-
},
|
|
150
|
-
"purpose": "Public login route for authentication flows."
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
"id": "auth.signout",
|
|
154
|
-
"path": "/auth/signout",
|
|
155
|
-
"scope": "surface",
|
|
156
|
-
"surface": "auth",
|
|
157
|
-
"name": "auth-signout",
|
|
158
|
-
"componentKey": "auth-signout",
|
|
159
|
-
"autoRegister": false,
|
|
160
|
-
"guard": {
|
|
161
|
-
"policy": "public"
|
|
162
|
-
},
|
|
163
|
-
"purpose": "Public sign-out route that clears session then returns to login."
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
"id": "auth.reset-password",
|
|
167
|
-
"path": "/auth/reset-password",
|
|
168
|
-
"scope": "surface",
|
|
169
|
-
"surface": "auth",
|
|
170
|
-
"name": "auth-reset-password",
|
|
171
|
-
"componentKey": "auth-reset-password",
|
|
172
|
-
"autoRegister": false,
|
|
173
|
-
"guard": {
|
|
174
|
-
"policy": "public"
|
|
175
|
-
},
|
|
176
|
-
"purpose": "Public password reset screen for recovery links."
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
"id": "auth.default-login",
|
|
180
|
-
"path": "/auth/default-login",
|
|
181
|
-
"scope": "surface",
|
|
182
|
-
"surface": "auth",
|
|
183
|
-
"name": "auth-default-login",
|
|
184
|
-
"componentKey": "auth-default-login",
|
|
185
|
-
"autoRegister": true,
|
|
186
|
-
"guard": {
|
|
187
|
-
"policy": "public"
|
|
188
|
-
},
|
|
189
|
-
"purpose": "Default module-supplied login screen."
|
|
190
|
-
}
|
|
191
|
-
],
|
|
192
|
-
"elements": [],
|
|
193
|
-
"overrides": [],
|
|
194
|
-
"placements": {
|
|
195
|
-
"outlets": [
|
|
196
|
-
{
|
|
197
|
-
"target": "auth-profile-menu:primary-menu",
|
|
198
|
-
"surfaces": ["*"],
|
|
199
|
-
"source": "src/client/views/AuthProfileWidget.vue"
|
|
200
|
-
}
|
|
201
|
-
],
|
|
202
|
-
"topology": {
|
|
203
|
-
"placements": [
|
|
204
|
-
{
|
|
205
|
-
"id": "auth.profile-menu",
|
|
206
|
-
"description": "Authenticated profile menu actions.",
|
|
207
|
-
"surfaces": ["*"],
|
|
208
|
-
"variants": {
|
|
209
|
-
"compact": {
|
|
210
|
-
"outlet": "auth-profile-menu:primary-menu",
|
|
211
|
-
"renderers": {
|
|
212
|
-
"link": "auth.web.profile.menu.link-item"
|
|
213
|
-
}
|
|
214
|
-
},
|
|
215
|
-
"medium": {
|
|
216
|
-
"outlet": "auth-profile-menu:primary-menu",
|
|
217
|
-
"renderers": {
|
|
218
|
-
"link": "auth.web.profile.menu.link-item"
|
|
219
|
-
}
|
|
220
|
-
},
|
|
221
|
-
"expanded": {
|
|
222
|
-
"outlet": "auth-profile-menu:primary-menu",
|
|
223
|
-
"renderers": {
|
|
224
|
-
"link": "auth.web.profile.menu.link-item"
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
]
|
|
230
|
-
},
|
|
231
|
-
"contributions": [
|
|
232
|
-
{
|
|
233
|
-
"id": "auth.profile.widget",
|
|
234
|
-
"target": "shell.status",
|
|
235
|
-
"kind": "component",
|
|
236
|
-
"surfaces": ["*"],
|
|
237
|
-
"order": 1000,
|
|
238
|
-
"componentToken": "auth.web.profile.widget",
|
|
239
|
-
"source": "mutations.text#auth-web-placement-block"
|
|
240
|
-
},
|
|
241
|
-
{
|
|
242
|
-
"id": "auth.profile.menu.sign-in",
|
|
243
|
-
"target": "auth.profile-menu",
|
|
244
|
-
"kind": "link",
|
|
245
|
-
"surfaces": ["*"],
|
|
246
|
-
"order": 200,
|
|
247
|
-
"when": "auth.authenticated !== true",
|
|
248
|
-
"source": "mutations.text#auth-web-placement-block"
|
|
249
|
-
},
|
|
250
|
-
{
|
|
251
|
-
"id": "auth.profile.menu.sign-out",
|
|
252
|
-
"target": "auth.profile-menu",
|
|
253
|
-
"kind": "link",
|
|
254
|
-
"surfaces": ["*"],
|
|
255
|
-
"order": 1000,
|
|
256
|
-
"when": "auth.authenticated === true",
|
|
257
|
-
"source": "mutations.text#auth-web-placement-block"
|
|
258
|
-
}
|
|
259
|
-
]
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
},
|
|
263
|
-
"mutations": {
|
|
264
|
-
"dependencies": {
|
|
265
|
-
"runtime": {
|
|
266
|
-
"@mdi/js": "^7.4.47",
|
|
267
|
-
"@jskit-ai/auth-core": "0.1.144",
|
|
268
|
-
"@jskit-ai/http-runtime": "0.1.144",
|
|
269
|
-
"@jskit-ai/kernel": "0.1.146",
|
|
270
|
-
"@jskit-ai/shell-web": "0.1.147"
|
|
271
|
-
},
|
|
272
|
-
"dev": {}
|
|
273
|
-
},
|
|
274
|
-
"packageJson": {
|
|
275
|
-
"scripts": {
|
|
276
|
-
"server:auth": "SERVER_SURFACE=auth node ./bin/server.js",
|
|
277
|
-
"dev:auth": "VITE_SURFACE=auth vite",
|
|
278
|
-
"build:auth": "VITE_SURFACE=auth vite build"
|
|
279
|
-
}
|
|
280
|
-
},
|
|
281
|
-
"procfile": {},
|
|
282
|
-
"files": [
|
|
283
|
-
{
|
|
284
|
-
"from": "templates/src/views/auth/LoginView.vue",
|
|
285
|
-
"to": "src/views/auth/LoginView.vue",
|
|
286
|
-
"ownership": "app",
|
|
287
|
-
"reason": "Install minimal login container that renders the module-provided DefaultLoginView by default.",
|
|
288
|
-
"category": "auth-web",
|
|
289
|
-
"id": "auth-view-login"
|
|
290
|
-
},
|
|
291
|
-
{
|
|
292
|
-
"from": "templates/src/views/auth/SignOutView.vue",
|
|
293
|
-
"to": "src/views/auth/SignOutView.vue",
|
|
294
|
-
"ownership": "app",
|
|
295
|
-
"reason": "Install minimal sign-out container that renders the module-provided SignOutView by default (edit the scaffolded file to customize).",
|
|
296
|
-
"category": "auth-web",
|
|
297
|
-
"id": "auth-view-signout"
|
|
298
|
-
},
|
|
299
|
-
{
|
|
300
|
-
"from": "templates/src/views/auth/ResetPasswordView.vue",
|
|
301
|
-
"to": "src/views/auth/ResetPasswordView.vue",
|
|
302
|
-
"ownership": "app",
|
|
303
|
-
"reason": "Install minimal password reset container that renders the module-provided DefaultResetPasswordView by default.",
|
|
304
|
-
"category": "auth-web",
|
|
305
|
-
"id": "auth-view-reset-password"
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
"from": "templates/src/pages/auth/login.vue",
|
|
309
|
-
"to": "src/pages/auth/login.vue",
|
|
310
|
-
"ownership": "app",
|
|
311
|
-
"reason": "Provide an auth-surface /auth/login wrapper that renders the package login view.",
|
|
312
|
-
"category": "auth-web",
|
|
313
|
-
"id": "auth-page-login"
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
"from": "templates/src/pages/auth/signout.vue",
|
|
317
|
-
"to": "src/pages/auth/signout.vue",
|
|
318
|
-
"ownership": "app",
|
|
319
|
-
"reason": "Provide an auth-surface /auth/signout wrapper that renders the package sign-out view.",
|
|
320
|
-
"category": "auth-web",
|
|
321
|
-
"id": "auth-page-signout"
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
"from": "templates/src/pages/auth/reset-password.vue",
|
|
325
|
-
"to": "src/pages/auth/reset-password.vue",
|
|
326
|
-
"ownership": "app",
|
|
327
|
-
"reason": "Provide an auth-surface /auth/reset-password wrapper that renders the package password reset view.",
|
|
328
|
-
"category": "auth-web",
|
|
329
|
-
"id": "auth-page-reset-password"
|
|
330
|
-
}
|
|
331
|
-
],
|
|
332
|
-
"text": [
|
|
333
|
-
{
|
|
334
|
-
"op": "append-text",
|
|
335
|
-
"file": "config/public.js",
|
|
336
|
-
"position": "bottom",
|
|
337
|
-
"skipIfContains": "config.surfaceDefinitions.auth = {",
|
|
338
|
-
"value": "\nconfig.surfaceDefinitions.auth = {\n id: \"auth\",\n label: \"Auth\",\n pagesRoot: \"auth\",\n enabled: true,\n requiresAuth: false,\n requiresWorkspace: false,\n origin: \"\"\n};\n",
|
|
339
|
-
"reason": "Register auth surface definition in public surface config.",
|
|
340
|
-
"category": "auth-web",
|
|
341
|
-
"id": "auth-web-surface-config-auth"
|
|
342
|
-
},
|
|
343
|
-
{
|
|
344
|
-
"op": "append-text",
|
|
345
|
-
"file": "src/placement.js",
|
|
346
|
-
"position": "bottom",
|
|
347
|
-
"skipIfContains": "id: \"auth.profile.widget\"",
|
|
348
|
-
"value": "\naddPlacement({\n id: \"auth.profile.widget\",\n target: \"shell.status\",\n kind: \"component\",\n surfaces: [\"*\"],\n order: 1000,\n componentToken: \"auth.web.profile.widget\"\n});\n\naddPlacement({\n id: \"auth.profile.menu.sign-in\",\n target: \"auth.profile-menu\",\n kind: \"link\",\n surfaces: [\"*\"],\n order: 200,\n props: {\n label: \"Sign in\",\n to: \"/auth/login\"\n },\n when: ({ auth }) => auth?.authenticated !== true\n});\n\naddPlacement({\n id: \"auth.profile.menu.sign-out\",\n target: \"auth.profile-menu\",\n kind: \"link\",\n surfaces: [\"*\"],\n order: 1000,\n props: {\n label: \"Sign out\",\n to: \"/auth/signout\"\n },\n when: ({ auth }) => auth?.authenticated === true\n});\n",
|
|
349
|
-
"reason": "Append auth profile placement entries into app-owned placement registry.",
|
|
350
|
-
"category": "auth-web",
|
|
351
|
-
"id": "auth-web-placement-block"
|
|
352
|
-
},
|
|
353
|
-
{
|
|
354
|
-
"op": "append-text",
|
|
355
|
-
"file": "src/placementTopology.js",
|
|
356
|
-
"position": "bottom",
|
|
357
|
-
"skipIfContains": "id: \"auth.profile-menu\"",
|
|
358
|
-
"value": "\naddPlacementTopology({\n id: \"auth.profile-menu\",\n description: \"Authenticated profile menu actions.\",\n surfaces: [\"*\"],\n variants: {\n compact: {\n outlet: \"auth-profile-menu:primary-menu\",\n renderers: {\n link: \"auth.web.profile.menu.link-item\"\n }\n },\n medium: {\n outlet: \"auth-profile-menu:primary-menu\",\n renderers: {\n link: \"auth.web.profile.menu.link-item\"\n }\n },\n expanded: {\n outlet: \"auth-profile-menu:primary-menu\",\n renderers: {\n link: \"auth.web.profile.menu.link-item\"\n }\n }\n }\n});\n",
|
|
359
|
-
"reason": "Append auth profile menu topology into the app-owned placement topology.",
|
|
360
|
-
"category": "auth-web",
|
|
361
|
-
"id": "auth-web-profile-menu-topology"
|
|
362
|
-
}
|
|
363
|
-
]
|
|
364
|
-
}
|
|
365
|
-
});
|