@authup/client-web-nuxt 1.0.0-beta.22 → 1.0.0-beta.24

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/dist/module.d.mts CHANGED
@@ -1,6 +1,15 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
- import { AuthupRuntimeOptions } from '../dist/runtime/types.js';
2
+ import { HookResult } from '@nuxt/schema';
3
+ import { MiddlewareHookPayload, RuntimeOptions } from '../dist/runtime/types.js';
3
4
 
4
- declare const _default: _nuxt_schema.NuxtModule<AuthupRuntimeOptions, AuthupRuntimeOptions, false>;
5
+ declare module '#app' {
6
+ interface RuntimeNuxtHooks {
7
+ 'authup:middleware:start': (data: MiddlewareHookPayload) => HookResult;
8
+ 'authup:middleware:redirect': (data: MiddlewareHookPayload) => HookResult;
9
+ 'authup:middleware:end': (data: MiddlewareHookPayload) => HookResult;
10
+ }
11
+ }
12
+
13
+ declare const _default: _nuxt_schema.NuxtModule<RuntimeOptions, RuntimeOptions, false>;
5
14
 
6
15
  export { _default as default };
package/dist/module.d.ts CHANGED
@@ -1,6 +1,15 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
- import { AuthupRuntimeOptions } from '../dist/runtime/types.js';
2
+ import { HookResult } from '@nuxt/schema';
3
+ import { MiddlewareHookPayload, RuntimeOptions } from '../dist/runtime/types.js';
3
4
 
4
- declare const _default: _nuxt_schema.NuxtModule<AuthupRuntimeOptions, AuthupRuntimeOptions, false>;
5
+ declare module '#app' {
6
+ interface RuntimeNuxtHooks {
7
+ 'authup:middleware:start': (data: MiddlewareHookPayload) => HookResult;
8
+ 'authup:middleware:redirect': (data: MiddlewareHookPayload) => HookResult;
9
+ 'authup:middleware:end': (data: MiddlewareHookPayload) => HookResult;
10
+ }
11
+ }
12
+
13
+ declare const _default: _nuxt_schema.NuxtModule<RuntimeOptions, RuntimeOptions, false>;
5
14
 
6
15
  export { _default as default };
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@authup/client-web-nuxt",
3
3
  "configKey": "authup",
4
- "version": "1.0.0-beta.22",
4
+ "version": "1.0.0-beta.24",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "0.8.4",
7
7
  "unbuild": "2.0.0"
package/dist/module.mjs CHANGED
@@ -34,8 +34,8 @@ const module = defineNuxtModule({
34
34
  addPlugin(path.resolve(runtimeDir, "plugins/kit"));
35
35
  addPlugin(path.resolve(runtimeDir, "plugins/root"));
36
36
  addRouteMiddleware({
37
- name: "loggedIn",
38
- path: path.resolve(runtimeDir, "middleware/00.session"),
37
+ name: "authup",
38
+ path: path.resolve(runtimeDir, "middleware/00.root"),
39
39
  global: true
40
40
  });
41
41
  }
@@ -1,2 +1 @@
1
- export * from './route-path.js';
2
- export * from './route-permissions.js';
1
+ export * from './routing-interceptor.js';
@@ -1,2 +1 @@
1
- export * from "./route-path.js";
2
- export * from "./route-permissions.js";
1
+ export * from "./routing-interceptor.js";
@@ -0,0 +1,18 @@
1
+ import { type Store, type StoreToRefs } from '@authup/client-web-kit';
2
+ import type { RouteLocationAsPathGeneric, RouteLocationNormalized } from 'vue-router';
3
+ import type { NuxtApp } from '#app';
4
+ export declare class RoutingInterceptor {
5
+ protected store: Store;
6
+ protected storeRefs: StoreToRefs<Store>;
7
+ protected homeRoute: string;
8
+ protected loginRoute: string;
9
+ constructor(nuxtApp: NuxtApp);
10
+ execute(to: RouteLocationNormalized, from: RouteLocationNormalized): Promise<RouteLocationAsPathGeneric | undefined>;
11
+ protected hasLoggedInCondition(route: RouteLocationNormalized): boolean;
12
+ protected validateLoggedInCondition(route: RouteLocationNormalized): boolean;
13
+ protected hasLoggedOutCondition(route: RouteLocationNormalized): boolean;
14
+ protected validateLoggedOutCondition(route: RouteLocationNormalized): boolean;
15
+ protected hasPermissionCondition(route: RouteLocationNormalized): boolean;
16
+ protected validatePermissionCondition(route: RouteLocationNormalized): Promise<boolean>;
17
+ protected hasQueryRedirectProperty(route: RouteLocationNormalized): boolean;
18
+ }
@@ -0,0 +1,138 @@
1
+ import {
2
+ injectStore,
3
+ storeToRefs
4
+ } from "@authup/client-web-kit";
5
+ import { hasOwnProperty } from "@authup/kit";
6
+ import { RouteMetaKey } from "../constants.js";
7
+ export class RoutingInterceptor {
8
+ store;
9
+ storeRefs;
10
+ homeRoute;
11
+ loginRoute;
12
+ constructor(nuxtApp) {
13
+ this.store = injectStore(nuxtApp.$pinia, nuxtApp.vueApp);
14
+ this.storeRefs = storeToRefs(this.store);
15
+ const runtimeOptions = nuxtApp.$config.public.authup;
16
+ this.homeRoute = runtimeOptions.homeRoute || "/";
17
+ this.loginRoute = runtimeOptions.loginRoute || "/login";
18
+ }
19
+ async execute(to, from) {
20
+ try {
21
+ await this.store.resolve();
22
+ } catch (e) {
23
+ await this.store.logout();
24
+ if (to.fullPath.startsWith(this.loginRoute)) {
25
+ return void 0;
26
+ }
27
+ return {
28
+ path: this.loginRoute,
29
+ query: {
30
+ ...!this.hasLoggedOutCondition(to) && !this.hasQueryRedirectProperty(to) ? { redirect: to.fullPath } : {}
31
+ }
32
+ };
33
+ }
34
+ let isValid = this.validateLoggedInCondition(to);
35
+ if (!isValid) {
36
+ return {
37
+ path: this.loginRoute,
38
+ query: {
39
+ ...!this.hasQueryRedirectProperty(to) ? { redirect: to.fullPath } : {}
40
+ }
41
+ };
42
+ }
43
+ isValid = this.validateLoggedOutCondition(to);
44
+ if (!isValid) {
45
+ await this.store.logout();
46
+ return void 0;
47
+ }
48
+ isValid = await this.validatePermissionCondition(to);
49
+ if (!isValid) {
50
+ if (from.path === to.path) {
51
+ await this.store.logout();
52
+ return {
53
+ path: this.loginRoute
54
+ };
55
+ }
56
+ if (this.hasLoggedOutCondition(from)) {
57
+ await this.store.logout();
58
+ return {
59
+ path: from.fullPath
60
+ };
61
+ }
62
+ return {
63
+ path: from.fullPath
64
+ };
65
+ }
66
+ return void 0;
67
+ }
68
+ hasLoggedInCondition(route) {
69
+ return route.matched.some(
70
+ (matched) => !!matched.meta[RouteMetaKey.REQUIRED_LOGGED_IN]
71
+ );
72
+ }
73
+ validateLoggedInCondition(route) {
74
+ if (!this.hasLoggedInCondition(route)) {
75
+ return true;
76
+ }
77
+ return !!this.storeRefs.loggedIn.value;
78
+ }
79
+ hasLoggedOutCondition(route) {
80
+ return route.matched.some(
81
+ (matched) => matched.meta[RouteMetaKey.REQUIRED_LOGGED_OUT]
82
+ );
83
+ }
84
+ validateLoggedOutCondition(route) {
85
+ if (!this.hasLoggedOutCondition(route)) {
86
+ return true;
87
+ }
88
+ return !this.storeRefs.loggedIn.value;
89
+ }
90
+ hasPermissionCondition(route) {
91
+ return route.matched.some(
92
+ (matched) => !!matched.meta[RouteMetaKey.REQUIRED_PERMISSIONS]
93
+ );
94
+ }
95
+ async validatePermissionCondition(route) {
96
+ if (!this.hasPermissionCondition(route)) {
97
+ return true;
98
+ }
99
+ let identity;
100
+ if (this.storeRefs.userId.value) {
101
+ identity = {
102
+ type: "user",
103
+ id: this.storeRefs.userId.value
104
+ };
105
+ }
106
+ for (let i = 0; i < route.matched.length; i++) {
107
+ const match = route.matched[i];
108
+ if (!match.meta || !hasOwnProperty(match.meta, RouteMetaKey.REQUIRED_PERMISSIONS)) {
109
+ continue;
110
+ }
111
+ let permissions = [];
112
+ if (match.meta[RouteMetaKey.REQUIRED_PERMISSIONS]) {
113
+ if (Array.isArray(match.meta[RouteMetaKey.REQUIRED_PERMISSIONS])) {
114
+ permissions = match.meta[RouteMetaKey.REQUIRED_PERMISSIONS];
115
+ } else if (typeof match.meta[RouteMetaKey.REQUIRED_PERMISSIONS] === "string") {
116
+ permissions = [match.meta[RouteMetaKey.REQUIRED_PERMISSIONS]];
117
+ }
118
+ }
119
+ if (permissions.length === 0) {
120
+ continue;
121
+ }
122
+ try {
123
+ await this.store.permissionChecker.preCheckOneOf({
124
+ name: permissions,
125
+ data: {
126
+ identity
127
+ }
128
+ });
129
+ } catch (e) {
130
+ return false;
131
+ }
132
+ }
133
+ return true;
134
+ }
135
+ hasQueryRedirectProperty(route) {
136
+ return route.query && !!route.query.redirect;
137
+ }
138
+ }
@@ -0,0 +1,2 @@
1
+ declare const _default: import("#app").RouteMiddleware;
2
+ export default _default;
@@ -0,0 +1,20 @@
1
+ import { defineNuxtRouteMiddleware, navigateTo, useNuxtApp } from "#imports";
2
+ import { RoutingInterceptor } from "../helpers/index.js";
3
+ export default defineNuxtRouteMiddleware(
4
+ async (to, from) => {
5
+ const nuxtApp = useNuxtApp();
6
+ const interceptor = new RoutingInterceptor(nuxtApp);
7
+ const hookPayload = {
8
+ to,
9
+ from
10
+ };
11
+ await nuxtApp.callHook("authup:middleware:start", hookPayload);
12
+ const redirectRoute = await interceptor.execute(to, from);
13
+ if (redirectRoute) {
14
+ await nuxtApp.callHook("authup:middleware:redirect", hookPayload);
15
+ return navigateTo(redirectRoute);
16
+ }
17
+ await nuxtApp.callHook("authup:middleware:end", hookPayload);
18
+ return void 0;
19
+ }
20
+ );
@@ -1,2 +1,2 @@
1
- declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
1
+ declare const _default: import("#app").Plugin<Record<string, unknown>> & import("#app").ObjectPlugin<Record<string, unknown>>;
2
2
  export default _default;
@@ -1,2 +1,2 @@
1
- declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
1
+ declare const _default: import("#app").Plugin<Record<string, unknown>> & import("#app").ObjectPlugin<Record<string, unknown>>;
2
2
  export default _default;
@@ -1,4 +1,4 @@
1
- export type AuthupRuntimeOptions = {
1
+ export type RuntimeOptions = {
2
2
  apiURL?: string;
3
3
  apiURLRuntimeKey?: string;
4
4
  cookieDomain?: string;
@@ -7,3 +7,11 @@ export type AuthupRuntimeOptions = {
7
7
  loginRoute?: string;
8
8
  logoutRoute?: string;
9
9
  };
10
+ export type MiddlewareHookPayload = {
11
+ to: {
12
+ fullPath: string;
13
+ };
14
+ from: {
15
+ fullPath: string;
16
+ };
17
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@authup/client-web-nuxt",
3
3
  "type": "module",
4
- "version": "1.0.0-beta.22",
4
+ "version": "1.0.0-beta.24",
5
5
  "description": "Nuxt module for the authup ecosystem",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -29,17 +29,18 @@
29
29
  "lint": "eslint ."
30
30
  },
31
31
  "dependencies": {
32
- "@authup/kit": "^1.0.0-beta.22",
33
- "@authup/client-web-kit": "^1.0.0-beta.22",
32
+ "@authup/kit": "^1.0.0-beta.24",
33
+ "@authup/client-web-kit": "^1.0.0-beta.24",
34
34
  "@nuxt/kit": "^3.13.2",
35
35
  "pathtrace": "^1.1.0",
36
36
  "smob": "^1.5.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@nuxt/module-builder": "^0.8.4",
40
- "@pinia/nuxt": "^0.5.5",
41
- "nuxt": "^3.13.2",
42
- "pinia": "^2.2.4"
40
+ "@pinia/nuxt": "^0.9.0",
41
+ "nuxt": "^3.15.2",
42
+ "pinia": "^2.2.4",
43
+ "vue-router": "^4.4.5"
43
44
  },
44
45
  "peerDependencies": {
45
46
  "@pinia/nuxt": "*",
@@ -1,7 +0,0 @@
1
- import type { RouteLocationNormalized } from 'vue-router';
2
- type RoutePathBuildOptions = {
3
- location?: RouteLocationNormalized;
4
- excluded?: string[];
5
- };
6
- export declare function buildRoutePath(context?: RoutePathBuildOptions): string | undefined;
7
- export {};
@@ -1,13 +0,0 @@
1
- export function buildRoutePath(context = {}) {
2
- if (!context.location || context.location.query.redirect) {
3
- return void 0;
4
- }
5
- if (context.excluded) {
6
- for (let i = 0; i < context.excluded.length; i++) {
7
- if (context.location.fullPath.startsWith(context.excluded[i])) {
8
- return void 0;
9
- }
10
- }
11
- }
12
- return context.location.fullPath;
13
- }
@@ -1,8 +0,0 @@
1
- import { type Store } from '@authup/client-web-kit';
2
- import type { RouteLocationNormalized } from 'vue-router';
3
- type RoutePermissionsCheckOptions = {
4
- routeLocation: RouteLocationNormalized;
5
- store: Store;
6
- };
7
- export declare function checkRoutePermissions(context: RoutePermissionsCheckOptions): Promise<boolean>;
8
- export {};
@@ -1,41 +0,0 @@
1
- import { storeToRefs } from "@authup/client-web-kit";
2
- import { hasOwnProperty } from "@authup/kit";
3
- import { RouteMetaKey } from "../constants.js";
4
- export async function checkRoutePermissions(context) {
5
- const storeRefs = storeToRefs(context.store);
6
- let identity;
7
- if (storeRefs.userId.value) {
8
- identity = {
9
- type: "user",
10
- id: storeRefs.userId.value
11
- };
12
- }
13
- for (let i = 0; i < context.routeLocation.matched.length; i++) {
14
- const match = context.routeLocation.matched[i];
15
- if (!match.meta || !hasOwnProperty(match.meta, RouteMetaKey.REQUIRED_PERMISSIONS)) {
16
- continue;
17
- }
18
- let permissions = [];
19
- if (match.meta[RouteMetaKey.REQUIRED_PERMISSIONS]) {
20
- if (Array.isArray(match.meta[RouteMetaKey.REQUIRED_PERMISSIONS])) {
21
- permissions = match.meta[RouteMetaKey.REQUIRED_PERMISSIONS];
22
- } else if (typeof match.meta[RouteMetaKey.REQUIRED_PERMISSIONS] === "string") {
23
- permissions = [match.meta[RouteMetaKey.REQUIRED_PERMISSIONS]];
24
- }
25
- }
26
- if (permissions.length === 0) {
27
- continue;
28
- }
29
- try {
30
- await context.store.permissionChecker.preCheckOneOf({
31
- name: permissions,
32
- data: {
33
- identity
34
- }
35
- });
36
- } catch (e) {
37
- return false;
38
- }
39
- }
40
- return true;
41
- }
@@ -1,2 +0,0 @@
1
- declare const _default: import("nuxt/app").RouteMiddleware;
2
- export default _default;
@@ -1,78 +0,0 @@
1
- import { storeToRefs, useStore } from "@authup/client-web-kit";
2
- import { defineNuxtRouteMiddleware, navigateTo, useRuntimeConfig } from "#imports";
3
- import { RouteMetaKey } from "../constants.js";
4
- import { buildRoutePath, checkRoutePermissions } from "../helpers/index.js";
5
- export default defineNuxtRouteMiddleware(
6
- async (to, from) => {
7
- const store = useStore();
8
- const storeRefs = storeToRefs(store);
9
- const runtimeConfig = useRuntimeConfig();
10
- const runtimeOptions = runtimeConfig.public.authup;
11
- const homeRoute = runtimeOptions.homeRoute || "/";
12
- const loginRoute = runtimeOptions.loginRoute || "/login";
13
- const logoutRoute = runtimeOptions.logoutRoute || "/logout";
14
- try {
15
- await store.resolve();
16
- } catch (e) {
17
- store.logout();
18
- const redirect = buildRoutePath({
19
- location: to,
20
- excluded: [
21
- logoutRoute,
22
- loginRoute
23
- ]
24
- });
25
- if (redirect) {
26
- return navigateTo({
27
- path: loginRoute,
28
- query: {
29
- redirect
30
- }
31
- });
32
- }
33
- return void 0;
34
- }
35
- const hasLoggedInProtection = to.matched.some(
36
- (matched) => !!matched.meta[RouteMetaKey.REQUIRED_LOGGED_IN]
37
- );
38
- if (hasLoggedInProtection && !storeRefs.loggedIn.value) {
39
- const redirect = buildRoutePath({
40
- location: to,
41
- excluded: [
42
- logoutRoute,
43
- loginRoute
44
- ]
45
- });
46
- return navigateTo({
47
- path: loginRoute,
48
- query: {
49
- ...redirect ? { redirect } : {}
50
- }
51
- });
52
- }
53
- const hasPermissionProtection = to.matched.some(
54
- (matched) => !!matched.meta[RouteMetaKey.REQUIRED_PERMISSIONS]
55
- );
56
- if (hasPermissionProtection) {
57
- const hasPermissions = await checkRoutePermissions({
58
- store,
59
- routeLocation: to
60
- });
61
- if (!hasPermissions) {
62
- return navigateTo({
63
- path: from ? from.fullPath : homeRoute
64
- });
65
- }
66
- }
67
- const hasLoggedOutProtection = to.matched.some(
68
- (matched) => matched.meta[RouteMetaKey.REQUIRED_LOGGED_OUT]
69
- );
70
- if (hasLoggedOutProtection && storeRefs.loggedIn.value) {
71
- store.logout();
72
- return navigateTo({
73
- path: to.fullPath
74
- });
75
- }
76
- return void 0;
77
- }
78
- );