@jskit-ai/auth-web 0.1.4

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.
Files changed (39) hide show
  1. package/package.descriptor.mjs +290 -0
  2. package/package.json +29 -0
  3. package/src/client/composables/useDefaultLoginView.js +935 -0
  4. package/src/client/composables/useDefaultSignOutView.js +113 -0
  5. package/src/client/index.js +19 -0
  6. package/src/client/lib/returnToPath.js +20 -0
  7. package/src/client/lib/surfaceLinkTarget.js +19 -0
  8. package/src/client/providers/AuthWebClientProvider.js +72 -0
  9. package/src/client/runtime/authGuardRuntime.js +499 -0
  10. package/src/client/runtime/authHttpClient.js +19 -0
  11. package/src/client/runtime/inject.js +43 -0
  12. package/src/client/runtime/tokens.js +7 -0
  13. package/src/client/runtime/useLoginView.js +7 -0
  14. package/src/client/runtime/useSignOut.js +121 -0
  15. package/src/client/views/AuthProfileMenuLinkItem.vue +83 -0
  16. package/src/client/views/AuthProfileWidget.vue +100 -0
  17. package/src/client/views/DefaultLoginView.vue +291 -0
  18. package/src/client/views/DefaultSignOutView.vue +58 -0
  19. package/src/server/constants/authActionIds.js +15 -0
  20. package/src/server/controllers/AuthController.js +183 -0
  21. package/src/server/providers/AuthRouteServiceProvider.js +31 -0
  22. package/src/server/providers/AuthWebServiceProvider.js +23 -0
  23. package/src/server/routes/authRoutes.js +244 -0
  24. package/src/server/services/AuthWebService.js +126 -0
  25. package/templates/src/pages/auth/login.vue +17 -0
  26. package/templates/src/pages/auth/signout.vue +17 -0
  27. package/templates/src/runtime/authGuardRuntime.js +7 -0
  28. package/templates/src/runtime/authHttpClient.js +1 -0
  29. package/templates/src/runtime/useSignOut.js +1 -0
  30. package/templates/src/views/auth/LoginView.vue +7 -0
  31. package/templates/src/views/auth/SignOutView.vue +7 -0
  32. package/test/authGuardRuntime.test.js +361 -0
  33. package/test/clientBoot.test.js +16 -0
  34. package/test/clientSurface.test.js +89 -0
  35. package/test/index.test.js +21 -0
  36. package/test/logoutFallback.test.js +50 -0
  37. package/test/providerRuntime.test.js +100 -0
  38. package/test/returnToPath.test.js +72 -0
  39. package/test/surfaceLinkTarget.test.js +80 -0
@@ -0,0 +1,183 @@
1
+ import { AUTH_ACTION_IDS } from "../constants/authActionIds.js";
2
+ import { AuthWebService } from "../services/AuthWebService.js";
3
+
4
+ class AuthController {
5
+ constructor({ service } = {}) {
6
+ if (!service) {
7
+ throw new Error("AuthController requires AuthWebService instance.");
8
+ }
9
+ this.service = service;
10
+ }
11
+
12
+ getOAuthProviderCatalogPayload() {
13
+ return this.service.getOAuthProviderCatalogPayload();
14
+ }
15
+
16
+ async register(request, reply) {
17
+ const payload = request.body || {};
18
+ const result = await this.service.register(request, payload);
19
+
20
+ this.service.writeSessionCookies(reply, result.session);
21
+
22
+ if (result.requiresEmailConfirmation) {
23
+ reply.code(201).send({
24
+ ok: true,
25
+ requiresEmailConfirmation: true,
26
+ message: "Check your email to confirm the account before logging in."
27
+ });
28
+ return;
29
+ }
30
+
31
+ reply.code(201).send({
32
+ ok: true,
33
+ username: result.profile.displayName,
34
+ requiresEmailConfirmation: false
35
+ });
36
+ }
37
+
38
+ async login(request, reply) {
39
+ const payload = request.body || {};
40
+ const result = await this.service.login(request, payload);
41
+
42
+ this.service.writeSessionCookies(reply, result.session);
43
+
44
+ reply.code(200).send({
45
+ ok: true,
46
+ username: result.profile.displayName
47
+ });
48
+ }
49
+
50
+ async requestOtpLogin(request, reply) {
51
+ const payload = request.body || {};
52
+ const result = await this.service.requestOtpLogin(request, payload);
53
+ reply.code(200).send(result);
54
+ }
55
+
56
+ async verifyOtpLogin(request, reply) {
57
+ const payload = request.body || {};
58
+ const result = await this.service.verifyOtpLogin(request, payload);
59
+
60
+ this.service.writeSessionCookies(reply, result.session);
61
+ reply.code(200).send({
62
+ ok: true,
63
+ username: result.profile.displayName,
64
+ email: result.profile.email
65
+ });
66
+ }
67
+
68
+ async oauthStart(request, reply) {
69
+ const provider = request.params?.provider;
70
+ const returnTo = request.query?.returnTo;
71
+ const result = await this.service.oauthStart(request, { provider, returnTo });
72
+ reply.redirect(result.url);
73
+ }
74
+
75
+ async oauthComplete(request, reply) {
76
+ const payload = request.body || {};
77
+ const result = await this.service.oauthComplete(request, payload);
78
+ this.service.writeSessionCookies(reply, result.session);
79
+
80
+ reply.code(200).send({
81
+ ok: true,
82
+ provider: result.provider,
83
+ username: result.profile.displayName,
84
+ email: result.profile.email
85
+ });
86
+ }
87
+
88
+ async logout(request, reply) {
89
+ let clearSession = true;
90
+ try {
91
+ const result = await this.service.logout(request);
92
+ clearSession = result?.clearSession !== false;
93
+ } catch (error) {
94
+ if (request?.log && typeof request.log.warn === "function") {
95
+ request.log.warn({ err: error }, "Auth logout fallback: clearing local session cookies.");
96
+ }
97
+ clearSession = true;
98
+ }
99
+
100
+ if (clearSession) {
101
+ this.service.clearSessionCookies(reply);
102
+ }
103
+
104
+ reply.code(200).send({
105
+ ok: true
106
+ });
107
+ }
108
+
109
+ async session(request, reply) {
110
+ const csrfToken = await reply.generateCsrf();
111
+ const oauthCatalogPayload = this.getOAuthProviderCatalogPayload();
112
+ const authResult = await this.service.session(request);
113
+
114
+ if (authResult.clearSession) {
115
+ this.service.clearSessionCookies(reply);
116
+ }
117
+ if (authResult.session) {
118
+ this.service.writeSessionCookies(reply, authResult.session);
119
+ }
120
+
121
+ if (authResult.transientFailure) {
122
+ reply.code(503).send({
123
+ error: "Authentication service temporarily unavailable. Please retry.",
124
+ csrfToken,
125
+ ...oauthCatalogPayload
126
+ });
127
+ return;
128
+ }
129
+
130
+ if (!authResult.authenticated) {
131
+ reply.code(200).send({
132
+ authenticated: false,
133
+ csrfToken,
134
+ ...oauthCatalogPayload
135
+ });
136
+ return;
137
+ }
138
+
139
+ reply.code(200).send({
140
+ authenticated: true,
141
+ username: authResult.profile.displayName,
142
+ csrfToken,
143
+ ...oauthCatalogPayload
144
+ });
145
+ }
146
+
147
+ async requestPasswordReset(request, reply) {
148
+ const payload = request.body || {};
149
+ const result = await this.service.requestPasswordReset(request, payload);
150
+ reply.code(200).send(result);
151
+ }
152
+
153
+ async completePasswordRecovery(request, reply) {
154
+ const payload = request.body || {};
155
+ const result = await this.service.completePasswordRecovery(request, payload);
156
+ this.service.writeSessionCookies(reply, result.session);
157
+ reply.code(200).send({
158
+ ok: true
159
+ });
160
+ }
161
+
162
+ async resetPassword(request, reply) {
163
+ const payload = request.body || {};
164
+ await this.service.resetPassword(request, payload);
165
+ this.service.clearSessionCookies(reply);
166
+ reply.code(200).send({
167
+ ok: true,
168
+ message: "Password updated. Sign in with your new password."
169
+ });
170
+ }
171
+ }
172
+
173
+ function createController({ service, authService } = {}) {
174
+ if (!service) {
175
+ if (!authService) {
176
+ throw new Error("createController requires either service or authService.");
177
+ }
178
+ service = new AuthWebService({ authService });
179
+ }
180
+ return new AuthController({ service });
181
+ }
182
+
183
+ export { AuthController, AUTH_ACTION_IDS, createController };
@@ -0,0 +1,31 @@
1
+ import { KERNEL_TOKENS } from "@jskit-ai/kernel/shared/support/tokens";
2
+ import { AuthController } from "../controllers/AuthController.js";
3
+ import { buildRoutes } from "../routes/authRoutes.js";
4
+
5
+ class AuthRouteServiceProvider {
6
+ static id = "auth.routes";
7
+
8
+ static dependsOn = ["auth.web"];
9
+
10
+ register(app) {
11
+ if (!app || typeof app.has !== "function") {
12
+ throw new Error("AuthRouteServiceProvider requires application has().");
13
+ }
14
+ }
15
+
16
+ boot(app) {
17
+ if (!app || typeof app.make !== "function") {
18
+ throw new Error("AuthRouteServiceProvider requires application make().");
19
+ }
20
+
21
+ const router = app.make(KERNEL_TOKENS.HttpRouter);
22
+ const authWebService = app.make("auth.web.service");
23
+ const controller = new AuthController({ service: authWebService });
24
+ const routes = buildRoutes(controller);
25
+ for (const route of routes) {
26
+ router.register(route.method, route.path, route, route.handler);
27
+ }
28
+ }
29
+ }
30
+
31
+ export { AuthRouteServiceProvider };
@@ -0,0 +1,23 @@
1
+ import { AuthWebService } from "../services/AuthWebService.js";
2
+
3
+ class AuthWebServiceProvider {
4
+ static id = "auth.web";
5
+
6
+ static dependsOn = ["auth.provider"];
7
+
8
+ register(app) {
9
+ if (!app || typeof app.singleton !== "function" || typeof app.has !== "function") {
10
+ throw new Error("AuthWebServiceProvider requires application singleton()/has().");
11
+ }
12
+ if (!app.has("actionExecutor")) {
13
+ throw new Error("AuthWebServiceProvider requires actionExecutor binding.");
14
+ }
15
+
16
+ app.singleton("auth.web.service", (scope) => {
17
+ const authService = scope.make("authService");
18
+ return new AuthWebService({ authService });
19
+ });
20
+ }
21
+ }
22
+
23
+ export { AuthWebServiceProvider };
@@ -0,0 +1,244 @@
1
+ import { withStandardErrorResponses } from "@jskit-ai/http-runtime/shared/validators/errorResponses";
2
+ import { authRegisterCommand } from "@jskit-ai/auth-core/shared/commands/authRegisterCommand";
3
+ import { authLoginPasswordCommand } from "@jskit-ai/auth-core/shared/commands/authLoginPasswordCommand";
4
+ import { authLoginOtpRequestCommand } from "@jskit-ai/auth-core/shared/commands/authLoginOtpRequestCommand";
5
+ import { authLoginOtpVerifyCommand } from "@jskit-ai/auth-core/shared/commands/authLoginOtpVerifyCommand";
6
+ import { authLoginOAuthStartCommand } from "@jskit-ai/auth-core/shared/commands/authLoginOAuthStartCommand";
7
+ import { authLoginOAuthCompleteCommand } from "@jskit-ai/auth-core/shared/commands/authLoginOAuthCompleteCommand";
8
+ import { authPasswordResetRequestCommand } from "@jskit-ai/auth-core/shared/commands/authPasswordResetRequestCommand";
9
+ import { authPasswordRecoveryCompleteCommand } from "@jskit-ai/auth-core/shared/commands/authPasswordRecoveryCompleteCommand";
10
+ import { authPasswordResetCommand } from "@jskit-ai/auth-core/shared/commands/authPasswordResetCommand";
11
+ import { authLogoutCommand } from "@jskit-ai/auth-core/shared/commands/authLogoutCommand";
12
+ import { authSessionReadCommand } from "@jskit-ai/auth-core/shared/commands/authSessionReadCommand";
13
+ import { AUTH_PATHS } from "@jskit-ai/auth-core/shared/authPaths";
14
+
15
+ function buildRoutes(controller) {
16
+ if (!controller) {
17
+ throw new Error("Auth routes require a controller instance.");
18
+ }
19
+
20
+ const handler = (methodName) => controller[methodName].bind(controller);
21
+
22
+ return [
23
+ {
24
+ path: AUTH_PATHS.REGISTER,
25
+ method: "POST",
26
+ auth: "public",
27
+ meta: {
28
+ tags: ["auth"],
29
+ summary: "Register a new user"
30
+ },
31
+ bodyValidator: authRegisterCommand.operation.bodyValidator,
32
+ responseValidators: withStandardErrorResponses(
33
+ {
34
+ 201: authRegisterCommand.operation.responseValidator
35
+ },
36
+ { includeValidation400: true }
37
+ ),
38
+ rateLimit: {
39
+ max: 10,
40
+ timeWindow: "1 minute"
41
+ },
42
+ handler: handler("register")
43
+ },
44
+ {
45
+ path: AUTH_PATHS.LOGIN,
46
+ method: "POST",
47
+ auth: "public",
48
+ meta: {
49
+ tags: ["auth"],
50
+ summary: "Log in with configured credentials"
51
+ },
52
+ bodyValidator: authLoginPasswordCommand.operation.bodyValidator,
53
+ responseValidators: withStandardErrorResponses(
54
+ {
55
+ 200: authLoginPasswordCommand.operation.responseValidator
56
+ },
57
+ { includeValidation400: true }
58
+ ),
59
+ rateLimit: {
60
+ max: 10,
61
+ timeWindow: "1 minute"
62
+ },
63
+ handler: handler("login")
64
+ },
65
+ {
66
+ path: AUTH_PATHS.LOGIN_OTP_REQUEST,
67
+ method: "POST",
68
+ auth: "public",
69
+ meta: {
70
+ tags: ["auth"],
71
+ summary: "Request one-time email login code"
72
+ },
73
+ bodyValidator: authLoginOtpRequestCommand.operation.bodyValidator,
74
+ responseValidators: withStandardErrorResponses(
75
+ {
76
+ 200: authLoginOtpRequestCommand.operation.responseValidator
77
+ },
78
+ { includeValidation400: true }
79
+ ),
80
+ rateLimit: {
81
+ max: 10,
82
+ timeWindow: "1 minute"
83
+ },
84
+ handler: handler("requestOtpLogin")
85
+ },
86
+ {
87
+ path: AUTH_PATHS.LOGIN_OTP_VERIFY,
88
+ method: "POST",
89
+ auth: "public",
90
+ meta: {
91
+ tags: ["auth"],
92
+ summary: "Verify one-time email login code and create session"
93
+ },
94
+ bodyValidator: authLoginOtpVerifyCommand.operation.bodyValidator,
95
+ responseValidators: withStandardErrorResponses(
96
+ {
97
+ 200: authLoginOtpVerifyCommand.operation.responseValidator
98
+ },
99
+ { includeValidation400: true }
100
+ ),
101
+ rateLimit: {
102
+ max: 10,
103
+ timeWindow: "1 minute"
104
+ },
105
+ handler: handler("verifyOtpLogin")
106
+ },
107
+ {
108
+ path: AUTH_PATHS.OAUTH_START_TEMPLATE,
109
+ method: "GET",
110
+ auth: "public",
111
+ csrfProtection: false,
112
+ meta: {
113
+ tags: ["auth"],
114
+ summary: "Start OAuth login with configured provider"
115
+ },
116
+ paramsValidator: authLoginOAuthStartCommand.operation.paramsValidator,
117
+ queryValidator: authLoginOAuthStartCommand.operation.queryValidator,
118
+ responseValidators: withStandardErrorResponses(
119
+ {
120
+ 302: authLoginOAuthStartCommand.operation.responseValidator
121
+ },
122
+ { includeValidation400: true }
123
+ ),
124
+ rateLimit: {
125
+ max: 20,
126
+ timeWindow: "1 minute"
127
+ },
128
+ handler: handler("oauthStart")
129
+ },
130
+ {
131
+ path: AUTH_PATHS.OAUTH_COMPLETE,
132
+ method: "POST",
133
+ auth: "public",
134
+ meta: {
135
+ tags: ["auth"],
136
+ summary: "Complete OAuth code exchange and set session cookies"
137
+ },
138
+ bodyValidator: authLoginOAuthCompleteCommand.operation.bodyValidator,
139
+ responseValidators: withStandardErrorResponses(
140
+ {
141
+ 200: authLoginOAuthCompleteCommand.operation.responseValidator
142
+ },
143
+ { includeValidation400: true }
144
+ ),
145
+ rateLimit: {
146
+ max: 20,
147
+ timeWindow: "1 minute"
148
+ },
149
+ handler: handler("oauthComplete")
150
+ },
151
+ {
152
+ path: AUTH_PATHS.PASSWORD_FORGOT,
153
+ method: "POST",
154
+ auth: "public",
155
+ meta: {
156
+ tags: ["auth"],
157
+ summary: "Request a password reset email"
158
+ },
159
+ bodyValidator: authPasswordResetRequestCommand.operation.bodyValidator,
160
+ responseValidators: withStandardErrorResponses(
161
+ {
162
+ 200: authPasswordResetRequestCommand.operation.responseValidator
163
+ },
164
+ { includeValidation400: true }
165
+ ),
166
+ rateLimit: {
167
+ max: 5,
168
+ timeWindow: "1 minute"
169
+ },
170
+ handler: handler("requestPasswordReset")
171
+ },
172
+ {
173
+ path: AUTH_PATHS.PASSWORD_RECOVERY,
174
+ method: "POST",
175
+ auth: "public",
176
+ meta: {
177
+ tags: ["auth"],
178
+ summary: "Complete password recovery link exchange"
179
+ },
180
+ bodyValidator: authPasswordRecoveryCompleteCommand.operation.bodyValidator,
181
+ responseValidators: withStandardErrorResponses(
182
+ {
183
+ 200: authPasswordRecoveryCompleteCommand.operation.responseValidator
184
+ },
185
+ { includeValidation400: true }
186
+ ),
187
+ rateLimit: {
188
+ max: 20,
189
+ timeWindow: "1 minute"
190
+ },
191
+ handler: handler("completePasswordRecovery")
192
+ },
193
+ {
194
+ path: AUTH_PATHS.PASSWORD_RESET,
195
+ method: "POST",
196
+ auth: "required",
197
+ meta: {
198
+ tags: ["auth"],
199
+ summary: "Set a new password for authenticated recovery session"
200
+ },
201
+ bodyValidator: authPasswordResetCommand.operation.bodyValidator,
202
+ responseValidators: withStandardErrorResponses(
203
+ {
204
+ 200: authPasswordResetCommand.operation.responseValidator
205
+ },
206
+ { includeValidation400: true }
207
+ ),
208
+ rateLimit: {
209
+ max: 20,
210
+ timeWindow: "1 minute"
211
+ },
212
+ handler: handler("resetPassword")
213
+ },
214
+ {
215
+ path: AUTH_PATHS.LOGOUT,
216
+ method: "POST",
217
+ auth: "public",
218
+ meta: {
219
+ tags: ["auth"],
220
+ summary: "Log out and clear session cookies"
221
+ },
222
+ responseValidators: withStandardErrorResponses({
223
+ 200: authLogoutCommand.operation.responseValidator
224
+ }),
225
+ handler: handler("logout")
226
+ },
227
+ {
228
+ path: AUTH_PATHS.SESSION,
229
+ method: "GET",
230
+ auth: "public",
231
+ meta: {
232
+ tags: ["auth"],
233
+ summary: "Get current session status and CSRF token"
234
+ },
235
+ responseValidators: withStandardErrorResponses({
236
+ 200: authSessionReadCommand.operation.responseValidator,
237
+ 503: authSessionReadCommand.operation.unavailableResponseValidator
238
+ }),
239
+ handler: handler("session")
240
+ }
241
+ ];
242
+ }
243
+
244
+ export { buildRoutes };
@@ -0,0 +1,126 @@
1
+ import { AUTH_ACTION_IDS } from "../constants/authActionIds.js";
2
+
3
+ class AuthWebService {
4
+ constructor({ authService } = {}) {
5
+ if (!authService) {
6
+ throw new Error("authService is required.");
7
+ }
8
+ this.authService = authService;
9
+ }
10
+
11
+ static get actionIds() {
12
+ return AUTH_ACTION_IDS;
13
+ }
14
+
15
+ async register(request, payload) {
16
+ return request.executeAction({
17
+ actionId: AUTH_ACTION_IDS.REGISTER,
18
+ input: payload
19
+ });
20
+ }
21
+
22
+ async login(request, payload) {
23
+ return request.executeAction({
24
+ actionId: AUTH_ACTION_IDS.LOGIN_PASSWORD,
25
+ input: payload
26
+ });
27
+ }
28
+
29
+ async requestOtpLogin(request, payload) {
30
+ return request.executeAction({
31
+ actionId: AUTH_ACTION_IDS.LOGIN_OTP_REQUEST,
32
+ input: payload
33
+ });
34
+ }
35
+
36
+ async verifyOtpLogin(request, payload) {
37
+ return request.executeAction({
38
+ actionId: AUTH_ACTION_IDS.LOGIN_OTP_VERIFY,
39
+ input: payload
40
+ });
41
+ }
42
+
43
+ async oauthStart(request, input) {
44
+ return request.executeAction({
45
+ actionId: AUTH_ACTION_IDS.LOGIN_OAUTH_START,
46
+ input
47
+ });
48
+ }
49
+
50
+ async oauthComplete(request, payload) {
51
+ return request.executeAction({
52
+ actionId: AUTH_ACTION_IDS.LOGIN_OAUTH_COMPLETE,
53
+ input: payload
54
+ });
55
+ }
56
+
57
+ async logout(request) {
58
+ return request.executeAction({
59
+ actionId: AUTH_ACTION_IDS.LOGOUT
60
+ });
61
+ }
62
+
63
+ async session(request) {
64
+ return request.executeAction({
65
+ actionId: AUTH_ACTION_IDS.SESSION_READ
66
+ });
67
+ }
68
+
69
+ async requestPasswordReset(request, payload) {
70
+ return request.executeAction({
71
+ actionId: AUTH_ACTION_IDS.PASSWORD_RESET_REQUEST,
72
+ input: payload
73
+ });
74
+ }
75
+
76
+ async completePasswordRecovery(request, payload) {
77
+ return request.executeAction({
78
+ actionId: AUTH_ACTION_IDS.PASSWORD_RECOVERY_COMPLETE,
79
+ input: payload
80
+ });
81
+ }
82
+
83
+ async resetPassword(request, payload) {
84
+ return request.executeAction({
85
+ actionId: AUTH_ACTION_IDS.PASSWORD_RESET,
86
+ input: payload
87
+ });
88
+ }
89
+
90
+ writeSessionCookies(reply, session) {
91
+ if (session && reply) {
92
+ this.authService.writeSessionCookies(reply, session);
93
+ }
94
+ }
95
+
96
+ clearSessionCookies(reply) {
97
+ if (reply) {
98
+ this.authService.clearSessionCookies(reply);
99
+ }
100
+ }
101
+
102
+ getOAuthProviderCatalogPayload() {
103
+ const catalog =
104
+ typeof this.authService.getOAuthProviderCatalog === "function"
105
+ ? this.authService.getOAuthProviderCatalog()
106
+ : null;
107
+ const providers = Array.isArray(catalog?.providers)
108
+ ? catalog.providers
109
+ .map((provider) => ({
110
+ id: String(provider?.id || "").trim().toLowerCase(),
111
+ label: String(provider?.label || "").trim()
112
+ }))
113
+ .filter((provider) => provider.id && provider.label)
114
+ : [];
115
+ const defaultProvider = String(catalog?.defaultProvider || "").trim().toLowerCase();
116
+
117
+ return {
118
+ oauthProviders: providers,
119
+ oauthDefaultProvider: providers.some((provider) => provider.id === defaultProvider)
120
+ ? defaultProvider
121
+ : null
122
+ };
123
+ }
124
+ }
125
+
126
+ export { AuthWebService };
@@ -0,0 +1,17 @@
1
+ <route lang="json">
2
+ {
3
+ "meta": {
4
+ "guard": {
5
+ "policy": "public"
6
+ }
7
+ }
8
+ }
9
+ </route>
10
+
11
+ <script setup>
12
+ import DefaultLoginView from "@jskit-ai/auth-web/client/views/DefaultLoginView";
13
+ </script>
14
+
15
+ <template>
16
+ <DefaultLoginView />
17
+ </template>
@@ -0,0 +1,17 @@
1
+ <route lang="json">
2
+ {
3
+ "meta": {
4
+ "guard": {
5
+ "policy": "public"
6
+ }
7
+ }
8
+ }
9
+ </route>
10
+
11
+ <script setup>
12
+ import DefaultSignOutView from "@jskit-ai/auth-web/client/views/DefaultSignOutView";
13
+ </script>
14
+
15
+ <template>
16
+ <DefaultSignOutView />
17
+ </template>
@@ -0,0 +1,7 @@
1
+ export {
2
+ createAuthGuardRuntime,
3
+ isAuthGuardRuntime,
4
+ initializeAuthGuardRuntime,
5
+ refreshAuthGuardState,
6
+ getAuthGuardState
7
+ } from "@jskit-ai/auth-web/client/runtime/authGuardRuntime";
@@ -0,0 +1 @@
1
+ export { authHttpRequest, clearAuthCsrfTokenCache } from "@jskit-ai/auth-web/client/runtime/authHttpClient";
@@ -0,0 +1 @@
1
+ export { useSignOut, createSignOutAction, performSignOutRequest } from "@jskit-ai/auth-web/client/runtime/useSignOut";
@@ -0,0 +1,7 @@
1
+ <script setup>
2
+ import DefaultLoginView from "@jskit-ai/auth-web/client/views/DefaultLoginView";
3
+ </script>
4
+
5
+ <template>
6
+ <DefaultLoginView />
7
+ </template>
@@ -0,0 +1,7 @@
1
+ <script setup>
2
+ import DefaultSignOutView from "@jskit-ai/auth-web/client/views/DefaultSignOutView";
3
+ </script>
4
+
5
+ <template>
6
+ <DefaultSignOutView />
7
+ </template>