nuxt-auther 1.0.2 → 1.0.3
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.cjs +5 -0
- package/dist/module.d.mts +3 -0
- package/dist/module.d.ts +3 -0
- package/dist/module.json +8 -0
- package/dist/module.mjs +1007 -0
- package/dist/runtime/composables.d.ts +2 -0
- package/dist/runtime/composables.mjs +2 -0
- package/dist/runtime/core/auth.d.ts +53 -0
- package/dist/runtime/core/auth.mjs +387 -0
- package/dist/runtime/core/index.d.ts +3 -0
- package/dist/runtime/core/index.mjs +3 -0
- package/dist/runtime/core/middleware.d.ts +2 -0
- package/dist/runtime/core/middleware.mjs +41 -0
- package/dist/runtime/core/storage.d.ts +41 -0
- package/dist/runtime/core/storage.mjs +277 -0
- package/dist/runtime/inc/configuration-document-request-error.d.ts +3 -0
- package/dist/runtime/inc/configuration-document-request-error.mjs +6 -0
- package/dist/runtime/inc/configuration-document.d.ts +26 -0
- package/dist/runtime/inc/configuration-document.mjs +94 -0
- package/dist/runtime/inc/default-properties.d.ts +123 -0
- package/dist/runtime/inc/default-properties.mjs +132 -0
- package/dist/runtime/inc/expired-auth-session-error.d.ts +3 -0
- package/dist/runtime/inc/expired-auth-session-error.mjs +6 -0
- package/dist/runtime/inc/id-token.d.ts +15 -0
- package/dist/runtime/inc/id-token.mjs +81 -0
- package/dist/runtime/inc/index.d.ts +10 -0
- package/dist/runtime/inc/index.mjs +10 -0
- package/dist/runtime/inc/refresh-controller.d.ts +9 -0
- package/dist/runtime/inc/refresh-controller.mjs +29 -0
- package/dist/runtime/inc/refresh-token.d.ts +14 -0
- package/dist/runtime/inc/refresh-token.mjs +75 -0
- package/dist/runtime/inc/request-handler.d.ts +17 -0
- package/dist/runtime/inc/request-handler.mjs +93 -0
- package/dist/runtime/inc/token-status.d.ts +12 -0
- package/dist/runtime/inc/token-status.mjs +39 -0
- package/dist/runtime/inc/token.d.ts +14 -0
- package/dist/runtime/inc/token.mjs +83 -0
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.mjs +3 -0
- package/dist/runtime/providers/auth0.d.ts +7 -0
- package/dist/runtime/providers/auth0.mjs +15 -0
- package/dist/runtime/providers/discord.d.ts +6 -0
- package/dist/runtime/providers/discord.mjs +18 -0
- package/dist/runtime/providers/facebook.d.ts +6 -0
- package/dist/runtime/providers/facebook.mjs +13 -0
- package/dist/runtime/providers/github.d.ts +6 -0
- package/dist/runtime/providers/github.mjs +15 -0
- package/dist/runtime/providers/google.d.ts +6 -0
- package/dist/runtime/providers/google.mjs +13 -0
- package/dist/runtime/providers/index.d.ts +8 -0
- package/dist/runtime/providers/index.mjs +8 -0
- package/dist/runtime/providers/laravel-jwt.d.ts +7 -0
- package/dist/runtime/providers/laravel-jwt.mjs +47 -0
- package/dist/runtime/providers/laravel-passport.d.ts +12 -0
- package/dist/runtime/providers/laravel-passport.mjs +69 -0
- package/dist/runtime/providers/laravel-sanctum.d.ts +6 -0
- package/dist/runtime/providers/laravel-sanctum.mjs +52 -0
- package/dist/runtime/schemes/auth0.d.ts +4 -0
- package/dist/runtime/schemes/auth0.mjs +13 -0
- package/dist/runtime/schemes/base.d.ts +8 -0
- package/dist/runtime/schemes/base.mjs +11 -0
- package/dist/runtime/schemes/cookie.d.ts +23 -0
- package/dist/runtime/schemes/cookie.mjs +111 -0
- package/dist/runtime/schemes/index.d.ts +8 -0
- package/dist/runtime/schemes/index.mjs +8 -0
- package/dist/runtime/schemes/laravel-jwt.d.ts +5 -0
- package/dist/runtime/schemes/laravel-jwt.mjs +6 -0
- package/dist/runtime/schemes/local.d.ts +38 -0
- package/dist/runtime/schemes/local.mjs +160 -0
- package/dist/runtime/schemes/oauth2.d.ts +61 -0
- package/dist/runtime/schemes/oauth2.mjs +374 -0
- package/dist/runtime/schemes/openIDConnect.d.ts +24 -0
- package/dist/runtime/schemes/openIDConnect.mjs +190 -0
- package/dist/runtime/schemes/refresh.d.ts +26 -0
- package/dist/runtime/schemes/refresh.mjs +141 -0
- package/dist/runtime/token-nitro.d.ts +2 -0
- package/dist/runtime/token-nitro.mjs +9 -0
- package/dist/types/index.d.ts +42 -0
- package/dist/types/openIDConnectConfigurationDocument.d.ts +31 -0
- package/dist/types/options.d.ts +125 -0
- package/dist/types/provider.d.ts +21 -0
- package/dist/types/request.d.ts +8 -0
- package/dist/types/router.d.ts +7 -0
- package/dist/types/scheme.d.ts +108 -0
- package/dist/types/store.d.ts +30 -0
- package/dist/types/strategy.d.ts +16 -0
- package/dist/types/utils.d.ts +5 -0
- package/dist/utils/index.d.ts +28 -0
- package/dist/utils/index.mjs +123 -0
- package/dist/utils/provider.d.ts +13 -0
- package/dist/utils/provider.mjs +360 -0
- package/package.json +5 -3
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { HTTPRequest, HTTPResponse, Scheme, SchemeCheck, TokenableScheme, RefreshableScheme, ModuleOptions, Route, AuthState } from '../../types';
|
|
2
|
+
import type { NuxtApp } from '#app';
|
|
3
|
+
import { Storage } from './storage';
|
|
4
|
+
export type ErrorListener = (...args: any[]) => void;
|
|
5
|
+
export type RedirectListener = (to: string, from: string) => string;
|
|
6
|
+
export declare class Auth {
|
|
7
|
+
#private;
|
|
8
|
+
ctx: NuxtApp;
|
|
9
|
+
options: ModuleOptions;
|
|
10
|
+
strategies: Record<string, Scheme>;
|
|
11
|
+
$storage: Storage;
|
|
12
|
+
$state: AuthState;
|
|
13
|
+
error?: Error;
|
|
14
|
+
constructor(ctx: NuxtApp, options: ModuleOptions);
|
|
15
|
+
getStrategy(throwException?: boolean): Scheme;
|
|
16
|
+
get tokenStrategy(): TokenableScheme;
|
|
17
|
+
get refreshStrategy(): RefreshableScheme;
|
|
18
|
+
get strategy(): Scheme;
|
|
19
|
+
get user(): AuthState['user'];
|
|
20
|
+
get loggedIn(): boolean;
|
|
21
|
+
get busy(): boolean;
|
|
22
|
+
init(): Promise<void>;
|
|
23
|
+
registerStrategy(name: string, strategy: Scheme): void;
|
|
24
|
+
setStrategy(name: string): Promise<HTTPResponse<any> | void>;
|
|
25
|
+
mounted(...args: any[]): Promise<HTTPResponse<any> | void>;
|
|
26
|
+
loginWith(name: string, ...args: any[]): Promise<HTTPResponse<any> | void>;
|
|
27
|
+
login(...args: any[]): Promise<HTTPResponse<any> | void>;
|
|
28
|
+
fetchUser(...args: any[]): Promise<HTTPResponse<any> | void>;
|
|
29
|
+
logout(...args: any[]): Promise<void>;
|
|
30
|
+
setUserToken(token: string | boolean, refreshToken?: string | boolean): Promise<HTTPResponse<any> | void>;
|
|
31
|
+
reset(...args: any[]): void;
|
|
32
|
+
refreshTokens(): Promise<HTTPResponse<any> | void>;
|
|
33
|
+
check(...args: any[]): SchemeCheck;
|
|
34
|
+
fetchUserOnce(...args: any[]): Promise<HTTPResponse<any> | void>;
|
|
35
|
+
setUser(user: AuthState | false, schemeCheck?: boolean): void;
|
|
36
|
+
request(endpoint: HTTPRequest, defaults?: HTTPRequest): Promise<HTTPResponse<any>>;
|
|
37
|
+
requestWith(endpoint?: HTTPRequest, defaults?: HTTPRequest): Promise<HTTPResponse<any>>;
|
|
38
|
+
wrapLogin(promise: Promise<HTTPResponse<any> | void>): Promise<HTTPResponse<any> | void>;
|
|
39
|
+
onError(listener: ErrorListener): void;
|
|
40
|
+
callOnError(error: Error, payload?: {}): void;
|
|
41
|
+
/**
|
|
42
|
+
*
|
|
43
|
+
* @param name redirect name
|
|
44
|
+
* @param route (default: false) Internal useRoute() (false) or manually specify
|
|
45
|
+
* @param router (default: true) Whether to use nuxt redirect (true) or window redirect (false)
|
|
46
|
+
*
|
|
47
|
+
* @returns
|
|
48
|
+
*/
|
|
49
|
+
redirect(name: string, route?: Route | false, router?: boolean): any;
|
|
50
|
+
onRedirect(listener: RedirectListener): void;
|
|
51
|
+
callOnRedirect(to: string, from: string): string;
|
|
52
|
+
hasScope(scope: string): boolean;
|
|
53
|
+
}
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
import { ExpiredAuthSessionError } from "../inc/expired-auth-session-error.mjs";
|
|
2
|
+
import { isSet, getProp, isRelativeURL, routeMeta, hasOwn } from "../../utils";
|
|
3
|
+
import { Storage } from "./storage.mjs";
|
|
4
|
+
import { isSamePath, withQuery } from "ufo";
|
|
5
|
+
import requrl from "requrl";
|
|
6
|
+
export class Auth {
|
|
7
|
+
ctx;
|
|
8
|
+
options;
|
|
9
|
+
strategies = {};
|
|
10
|
+
$storage;
|
|
11
|
+
$state;
|
|
12
|
+
error;
|
|
13
|
+
#errorListeners = [];
|
|
14
|
+
#redirectListeners = [];
|
|
15
|
+
#tokenValidationInterval;
|
|
16
|
+
constructor(ctx, options) {
|
|
17
|
+
this.ctx = ctx;
|
|
18
|
+
if (typeof this.ctx.$localePath === "function") {
|
|
19
|
+
this.ctx.hook("i18n:localeSwitched", () => {
|
|
20
|
+
this.#transformRedirect(this.options.redirect);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
this.#transformRedirect(options.redirect);
|
|
24
|
+
this.options = options;
|
|
25
|
+
const initialState = {
|
|
26
|
+
user: void 0,
|
|
27
|
+
loggedIn: false,
|
|
28
|
+
strategy: void 0,
|
|
29
|
+
busy: false
|
|
30
|
+
};
|
|
31
|
+
const storage = new Storage(ctx, {
|
|
32
|
+
...this.options,
|
|
33
|
+
initialState
|
|
34
|
+
});
|
|
35
|
+
this.$storage = storage;
|
|
36
|
+
this.$state = storage.state;
|
|
37
|
+
}
|
|
38
|
+
#transformRedirect(redirects) {
|
|
39
|
+
for (const key in redirects) {
|
|
40
|
+
const value = redirects[key];
|
|
41
|
+
if (typeof value === "string" && typeof this.ctx.$localePath === "function") {
|
|
42
|
+
redirects[key] = this.ctx.$localePath(value);
|
|
43
|
+
}
|
|
44
|
+
if (typeof value === "function") {
|
|
45
|
+
redirects[key] = value(this, typeof this.ctx.$localePath === "function" ? this.ctx.$localePath : void 0);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return redirects;
|
|
49
|
+
}
|
|
50
|
+
#checkTokenValidation() {
|
|
51
|
+
this.#tokenValidationInterval = setInterval(async () => {
|
|
52
|
+
const { valid, tokenExpired, refreshTokenExpired, isRefreshable } = this.check(true);
|
|
53
|
+
let isValid = valid;
|
|
54
|
+
if (refreshTokenExpired) {
|
|
55
|
+
this.reset?.();
|
|
56
|
+
clearInterval(this.#tokenValidationInterval);
|
|
57
|
+
throw new ExpiredAuthSessionError();
|
|
58
|
+
}
|
|
59
|
+
if (tokenExpired) {
|
|
60
|
+
if (!isRefreshable) {
|
|
61
|
+
this.reset();
|
|
62
|
+
clearInterval(this.#tokenValidationInterval);
|
|
63
|
+
throw new ExpiredAuthSessionError();
|
|
64
|
+
}
|
|
65
|
+
isValid = await this.refreshStrategy.refreshController.handleRefresh().then(() => true).catch(() => {
|
|
66
|
+
this.reset();
|
|
67
|
+
clearInterval(this.#tokenValidationInterval);
|
|
68
|
+
throw new ExpiredAuthSessionError();
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const token = this.tokenStrategy.token;
|
|
72
|
+
if (!isValid) {
|
|
73
|
+
if (token && !token.get()) {
|
|
74
|
+
clearInterval(this.#tokenValidationInterval);
|
|
75
|
+
throw new ExpiredAuthSessionError();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}, typeof this.options.tokenValidationInterval === "number" ? this.options.tokenValidationInterval : 1e3);
|
|
79
|
+
}
|
|
80
|
+
getStrategy(throwException = true) {
|
|
81
|
+
if (throwException) {
|
|
82
|
+
if (!this.$state.strategy) {
|
|
83
|
+
throw new Error("No strategy is set!");
|
|
84
|
+
}
|
|
85
|
+
if (!this.strategies[this.$state.strategy]) {
|
|
86
|
+
throw new Error("Strategy not supported: " + this.$state.strategy);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return this.strategies[this.$state.strategy];
|
|
90
|
+
}
|
|
91
|
+
get tokenStrategy() {
|
|
92
|
+
return this.getStrategy();
|
|
93
|
+
}
|
|
94
|
+
get refreshStrategy() {
|
|
95
|
+
return this.getStrategy();
|
|
96
|
+
}
|
|
97
|
+
get strategy() {
|
|
98
|
+
return this.getStrategy();
|
|
99
|
+
}
|
|
100
|
+
get user() {
|
|
101
|
+
return this.$state.user;
|
|
102
|
+
}
|
|
103
|
+
// ---------------------------------------------------------------
|
|
104
|
+
// Strategy and Scheme
|
|
105
|
+
// ---------------------------------------------------------------
|
|
106
|
+
get loggedIn() {
|
|
107
|
+
return this.$state.loggedIn;
|
|
108
|
+
}
|
|
109
|
+
get busy() {
|
|
110
|
+
return this.$storage.getState("busy");
|
|
111
|
+
}
|
|
112
|
+
async init() {
|
|
113
|
+
if (this.options.resetOnError) {
|
|
114
|
+
this.onError((...args) => {
|
|
115
|
+
if (typeof this.options.resetOnError !== "function" || this.options.resetOnError(...args)) {
|
|
116
|
+
this.reset();
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
this.$storage.syncUniversal("strategy", this.options.defaultStrategy, { cookie: this.$state.loggedIn });
|
|
121
|
+
if (!this.getStrategy(false)) {
|
|
122
|
+
this.$storage.setUniversal("strategy", this.options.defaultStrategy, { cookie: this.$state.loggedIn });
|
|
123
|
+
if (!this.getStrategy(false)) {
|
|
124
|
+
return Promise.resolve();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
await this.mounted();
|
|
129
|
+
} catch (error) {
|
|
130
|
+
this.callOnError(error);
|
|
131
|
+
} finally {
|
|
132
|
+
if (process.client && this.options.watchLoggedIn) {
|
|
133
|
+
const enableTokenValidation = !this.#tokenValidationInterval && this.refreshStrategy.token && this.options.tokenValidationInterval;
|
|
134
|
+
this.$storage.watchState("loggedIn", (loggedIn) => {
|
|
135
|
+
if (hasOwn(this.ctx.$router.currentRoute.value.meta, "auth") && !routeMeta(this.ctx.$router.currentRoute.value, "auth", false)) {
|
|
136
|
+
this.redirect(loggedIn ? "home" : "logout");
|
|
137
|
+
}
|
|
138
|
+
if (enableTokenValidation && loggedIn) {
|
|
139
|
+
this.#checkTokenValidation();
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
if (enableTokenValidation && this.loggedIn) {
|
|
143
|
+
this.#checkTokenValidation();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
registerStrategy(name, strategy) {
|
|
149
|
+
this.strategies[name] = strategy;
|
|
150
|
+
}
|
|
151
|
+
async setStrategy(name) {
|
|
152
|
+
if (name === this.$storage.getUniversal("strategy")) {
|
|
153
|
+
return Promise.resolve();
|
|
154
|
+
}
|
|
155
|
+
if (!this.strategies[name]) {
|
|
156
|
+
throw new Error(`Strategy ${name} is not defined!`);
|
|
157
|
+
}
|
|
158
|
+
this.reset();
|
|
159
|
+
this.$storage.setUniversal("strategy", name, { cookie: this.$state.loggedIn });
|
|
160
|
+
return this.mounted();
|
|
161
|
+
}
|
|
162
|
+
async mounted(...args) {
|
|
163
|
+
if (!this.strategy.mounted) {
|
|
164
|
+
return this.fetchUserOnce();
|
|
165
|
+
}
|
|
166
|
+
return Promise.resolve(this.strategy.mounted(...args)).catch(
|
|
167
|
+
(error) => {
|
|
168
|
+
this.callOnError(error, { method: "mounted" });
|
|
169
|
+
return Promise.reject(error);
|
|
170
|
+
}
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
async loginWith(name, ...args) {
|
|
174
|
+
return this.setStrategy(name).then(() => this.login(...args));
|
|
175
|
+
}
|
|
176
|
+
async login(...args) {
|
|
177
|
+
if (!this.strategy.login) {
|
|
178
|
+
return Promise.resolve();
|
|
179
|
+
}
|
|
180
|
+
return this.wrapLogin(this.strategy.login(...args)).catch(
|
|
181
|
+
(error) => {
|
|
182
|
+
this.callOnError(error, { method: "login" });
|
|
183
|
+
return Promise.reject(error);
|
|
184
|
+
}
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
async fetchUser(...args) {
|
|
188
|
+
if (!this.strategy.fetchUser) {
|
|
189
|
+
return Promise.resolve();
|
|
190
|
+
}
|
|
191
|
+
return Promise.resolve(this.strategy.fetchUser(...args)).catch(
|
|
192
|
+
(error) => {
|
|
193
|
+
this.callOnError(error, { method: "fetchUser" });
|
|
194
|
+
return Promise.reject(error);
|
|
195
|
+
}
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
async logout(...args) {
|
|
199
|
+
this.$storage.removeCookie("strategy");
|
|
200
|
+
if (!this.strategy.logout) {
|
|
201
|
+
this.reset();
|
|
202
|
+
return Promise.resolve();
|
|
203
|
+
}
|
|
204
|
+
return Promise.resolve(this.strategy.logout(...args)).catch(
|
|
205
|
+
(error) => {
|
|
206
|
+
this.callOnError(error, { method: "logout" });
|
|
207
|
+
return Promise.reject(error);
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
// ---------------------------------------------------------------
|
|
212
|
+
// User helpers
|
|
213
|
+
// ---------------------------------------------------------------
|
|
214
|
+
async setUserToken(token, refreshToken) {
|
|
215
|
+
if (!this.tokenStrategy.setUserToken) {
|
|
216
|
+
this.tokenStrategy.token.set(token);
|
|
217
|
+
return Promise.resolve();
|
|
218
|
+
}
|
|
219
|
+
return Promise.resolve(this.tokenStrategy.setUserToken(token, refreshToken)).catch((error) => {
|
|
220
|
+
this.callOnError(error, { method: "setUserToken" });
|
|
221
|
+
return Promise.reject(error);
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
reset(...args) {
|
|
225
|
+
if (this.tokenStrategy.token && !this.strategy.reset) {
|
|
226
|
+
this.setUser(false);
|
|
227
|
+
this.tokenStrategy.token.reset();
|
|
228
|
+
this.refreshStrategy.refreshToken.reset();
|
|
229
|
+
}
|
|
230
|
+
return this.strategy.reset(...args);
|
|
231
|
+
}
|
|
232
|
+
async refreshTokens() {
|
|
233
|
+
if (!this.refreshStrategy.refreshController) {
|
|
234
|
+
return Promise.resolve();
|
|
235
|
+
}
|
|
236
|
+
return Promise.resolve(this.refreshStrategy.refreshController.handleRefresh()).catch((error) => {
|
|
237
|
+
this.callOnError(error, { method: "refreshTokens" });
|
|
238
|
+
return Promise.reject(error);
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
check(...args) {
|
|
242
|
+
if (!this.strategy.check) {
|
|
243
|
+
return { valid: true };
|
|
244
|
+
}
|
|
245
|
+
return this.strategy.check(...args);
|
|
246
|
+
}
|
|
247
|
+
async fetchUserOnce(...args) {
|
|
248
|
+
if (!this.$state.user) {
|
|
249
|
+
return this.fetchUser(...args);
|
|
250
|
+
}
|
|
251
|
+
return Promise.resolve();
|
|
252
|
+
}
|
|
253
|
+
// ---------------------------------------------------------------
|
|
254
|
+
// Utils
|
|
255
|
+
// ---------------------------------------------------------------
|
|
256
|
+
setUser(user, schemeCheck = true) {
|
|
257
|
+
this.$storage.setState("user", user);
|
|
258
|
+
let check = { valid: Boolean(user) };
|
|
259
|
+
if (schemeCheck && check.valid) {
|
|
260
|
+
check = this.check();
|
|
261
|
+
}
|
|
262
|
+
this.$storage.setState("loggedIn", check.valid);
|
|
263
|
+
}
|
|
264
|
+
async request(endpoint, defaults = {}) {
|
|
265
|
+
const request = typeof defaults === "object" ? Object.assign({}, defaults, endpoint) : endpoint;
|
|
266
|
+
if (request.baseURL === "") {
|
|
267
|
+
request.baseURL = requrl(process.server ? this.ctx.ssrContext.event.node.req : void 0);
|
|
268
|
+
}
|
|
269
|
+
if (!this.ctx.$http) {
|
|
270
|
+
return Promise.reject(new Error("[AUTH] add the @nuxt-alt/http module to nuxt.config file"));
|
|
271
|
+
}
|
|
272
|
+
const $http = process.server && this.ctx.ssrContext ? this.ctx.ssrContext.event.$http.raw(request) : this.ctx.$http.raw(request);
|
|
273
|
+
return $http.catch((error) => {
|
|
274
|
+
this.callOnError(error, { method: "request" });
|
|
275
|
+
return Promise.reject(error);
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
async requestWith(endpoint, defaults) {
|
|
279
|
+
const request = Object.assign({}, defaults, endpoint);
|
|
280
|
+
if (this.tokenStrategy.token) {
|
|
281
|
+
const token = this.tokenStrategy.token.get();
|
|
282
|
+
const tokenName = this.tokenStrategy.options.token.name || "Authorization";
|
|
283
|
+
if (!request.headers) {
|
|
284
|
+
request.headers = {};
|
|
285
|
+
}
|
|
286
|
+
if (!request.headers[tokenName] && isSet(token) && token && typeof token === "string") {
|
|
287
|
+
request.headers[tokenName] = token;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return this.request(request);
|
|
291
|
+
}
|
|
292
|
+
async wrapLogin(promise) {
|
|
293
|
+
this.$storage.setState("busy", true);
|
|
294
|
+
this.error = void 0;
|
|
295
|
+
return Promise.resolve(promise).then((response) => {
|
|
296
|
+
this.$storage.setState("busy", false);
|
|
297
|
+
this.$storage.syncUniversal("strategy", this.strategy.name);
|
|
298
|
+
return response;
|
|
299
|
+
}).catch((error) => {
|
|
300
|
+
this.$storage.setState("busy", false);
|
|
301
|
+
return Promise.reject(error);
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
onError(listener) {
|
|
305
|
+
this.#errorListeners.push(listener);
|
|
306
|
+
}
|
|
307
|
+
callOnError(error, payload = {}) {
|
|
308
|
+
this.error = error;
|
|
309
|
+
for (const fn of this.#errorListeners) {
|
|
310
|
+
fn(error, payload);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
*
|
|
315
|
+
* @param name redirect name
|
|
316
|
+
* @param route (default: false) Internal useRoute() (false) or manually specify
|
|
317
|
+
* @param router (default: true) Whether to use nuxt redirect (true) or window redirect (false)
|
|
318
|
+
*
|
|
319
|
+
* @returns
|
|
320
|
+
*/
|
|
321
|
+
redirect(name, route = false, router = true) {
|
|
322
|
+
if (!this.options.redirect) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
let to = this.options.redirect[name];
|
|
326
|
+
if (!to) {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
const currentRoute = this.ctx.$router.currentRoute.value;
|
|
330
|
+
const nuxtRoute = this.options.fullPathRedirect ? currentRoute.fullPath : currentRoute.path;
|
|
331
|
+
const from = route ? this.options.fullPathRedirect ? route.fullPath : route.path : nuxtRoute;
|
|
332
|
+
const queryReturnTo = currentRoute.query.to;
|
|
333
|
+
if (this.options.rewriteRedirects) {
|
|
334
|
+
if (["logout", "login"].includes(name) && isRelativeURL(from) && !isSamePath(to, from)) {
|
|
335
|
+
if (this.options.redirectStrategy === "query") {
|
|
336
|
+
to = to + "?to=" + encodeURIComponent(queryReturnTo ? queryReturnTo : from);
|
|
337
|
+
}
|
|
338
|
+
if (this.options.redirectStrategy === "storage") {
|
|
339
|
+
this.$storage.setUniversal("redirect", from);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
if (name === "home") {
|
|
343
|
+
let redirect = currentRoute.query.to ? decodeURIComponent(currentRoute.query.to) : void 0;
|
|
344
|
+
if (this.options.redirectStrategy === "storage") {
|
|
345
|
+
redirect = this.$storage.getUniversal("redirect");
|
|
346
|
+
this.$storage.setUniversal("redirect", null);
|
|
347
|
+
}
|
|
348
|
+
if (redirect) {
|
|
349
|
+
to = redirect;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
to = this.callOnRedirect(to, from) || to;
|
|
354
|
+
if (isSamePath(to, from)) {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
if (this.options.redirectStrategy === "storage") {
|
|
358
|
+
if (this.options.fullPathRedirect) {
|
|
359
|
+
to = withQuery(to, currentRoute.query);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if (process.client && (!router || !isRelativeURL(to))) {
|
|
363
|
+
return globalThis.location.replace(to);
|
|
364
|
+
} else {
|
|
365
|
+
return this.ctx.$router.push(typeof this.ctx.$localePath === "function" ? this.ctx.$localePath(to) : to);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
onRedirect(listener) {
|
|
369
|
+
this.#redirectListeners.push(listener);
|
|
370
|
+
}
|
|
371
|
+
callOnRedirect(to, from) {
|
|
372
|
+
for (const fn of this.#redirectListeners) {
|
|
373
|
+
to = fn(to, from) || to;
|
|
374
|
+
}
|
|
375
|
+
return to;
|
|
376
|
+
}
|
|
377
|
+
hasScope(scope) {
|
|
378
|
+
const userScopes = this.$state.user && getProp(this.$state.user, this.options.scopeKey);
|
|
379
|
+
if (!userScopes) {
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
if (Array.isArray(userScopes)) {
|
|
383
|
+
return userScopes.includes(scope);
|
|
384
|
+
}
|
|
385
|
+
return Boolean(getProp(userScopes, scope));
|
|
386
|
+
}
|
|
387
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { routeMeta, getMatchedComponents, hasOwn, normalizePath } from "../../utils";
|
|
2
|
+
import { useAuth, useNuxtApp, defineNuxtRouteMiddleware } from "#imports";
|
|
3
|
+
export default defineNuxtRouteMiddleware(async (to, from) => {
|
|
4
|
+
if (hasOwn(to.meta, "auth") && routeMeta(to, "auth", false)) {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
const matches = [];
|
|
8
|
+
const Components = getMatchedComponents(to, matches);
|
|
9
|
+
if (!Components.length) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const auth = useAuth();
|
|
13
|
+
const ctx = useNuxtApp();
|
|
14
|
+
const { login, callback } = auth.options.redirect;
|
|
15
|
+
const pageIsInGuestMode = hasOwn(to.meta, "auth") && routeMeta(to, "auth", "guest");
|
|
16
|
+
const insidePage = (page) => normalizePath(to.path, ctx) === normalizePath(page, ctx);
|
|
17
|
+
if (auth.$state.loggedIn) {
|
|
18
|
+
const { tokenExpired, refreshTokenExpired, isRefreshable } = auth.check(true);
|
|
19
|
+
if (!login || insidePage(login) || pageIsInGuestMode) {
|
|
20
|
+
return auth.redirect("home", to);
|
|
21
|
+
}
|
|
22
|
+
if (refreshTokenExpired) {
|
|
23
|
+
auth.reset();
|
|
24
|
+
return auth.redirect("login", to);
|
|
25
|
+
} else if (tokenExpired) {
|
|
26
|
+
if (isRefreshable) {
|
|
27
|
+
try {
|
|
28
|
+
await auth.refreshTokens();
|
|
29
|
+
} catch (error) {
|
|
30
|
+
auth.reset();
|
|
31
|
+
return auth.redirect("login", to);
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
auth.reset();
|
|
35
|
+
return auth.redirect("login", to);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
} else if (!pageIsInGuestMode && (!callback || !insidePage(callback))) {
|
|
39
|
+
return auth.redirect("login", to);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ModuleOptions, AuthStore, AuthState, StoreIncludeOptions } from '../../types';
|
|
2
|
+
import type { NuxtApp } from '#app';
|
|
3
|
+
import { type CookieSerializeOptions } from 'cookie-es';
|
|
4
|
+
import { type Ref } from 'vue';
|
|
5
|
+
/**
|
|
6
|
+
* @class Storage
|
|
7
|
+
* @classdesc Storage class for stores and cookies
|
|
8
|
+
* @param { NuxtApp } ctx - Nuxt app context
|
|
9
|
+
* @param { ModuleOptions } options - Module options
|
|
10
|
+
*/
|
|
11
|
+
export declare class Storage {
|
|
12
|
+
#private;
|
|
13
|
+
ctx: NuxtApp;
|
|
14
|
+
options: ModuleOptions;
|
|
15
|
+
state: AuthState;
|
|
16
|
+
memory: AuthState;
|
|
17
|
+
constructor(ctx: NuxtApp, options: ModuleOptions);
|
|
18
|
+
setUniversal<V extends any>(key: string, value: V, include?: StoreIncludeOptions): V | void;
|
|
19
|
+
getUniversal(key: string): any;
|
|
20
|
+
syncUniversal(key: string, defaultValue?: any, include?: StoreIncludeOptions): any;
|
|
21
|
+
removeUniversal(key: string): void;
|
|
22
|
+
get pinia(): AuthStore;
|
|
23
|
+
get store(): Ref<AuthState, AuthState>;
|
|
24
|
+
setState(key: string, value: any): unknown;
|
|
25
|
+
getState(key: string): unknown;
|
|
26
|
+
watchState(watchKey: string, fn: (value: any) => void): void;
|
|
27
|
+
removeState(key: string): void;
|
|
28
|
+
setLocalStorage<V extends any>(key: string, value: V): V | void;
|
|
29
|
+
getLocalStorage(key: string): any;
|
|
30
|
+
removeLocalStorage(key: string): void;
|
|
31
|
+
isLocalStorageEnabled(): boolean;
|
|
32
|
+
setSessionStorage<V extends any>(key: string, value: V): V | void;
|
|
33
|
+
getSessionStorage(key: string): any;
|
|
34
|
+
removeSessionStorage(key: string): void;
|
|
35
|
+
isSessionStorageEnabled(): boolean;
|
|
36
|
+
setCookie<V extends any>(key: string, value: V, options?: CookieSerializeOptions): void;
|
|
37
|
+
getCookies(): Record<string, any> | void;
|
|
38
|
+
getCookie(key: string): string | null | undefined;
|
|
39
|
+
removeCookie(key: string, options?: CookieSerializeOptions): void;
|
|
40
|
+
isCookiesEnabled(): boolean;
|
|
41
|
+
}
|