@dehwyyy/auth 1.0.5 → 2.0.0
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/README.md +185 -50
- package/dist/v2/auth/client/baseClient.d.ts +2 -0
- package/dist/v2/auth/client/baseClient.js +14 -0
- package/dist/v2/auth/client/client.d.ts +3 -0
- package/dist/v2/auth/client/client.js +7 -0
- package/dist/v2/auth/client/index.d.ts +3 -0
- package/dist/v2/auth/client/index.js +3 -0
- package/dist/v2/auth/factory.d.ts +20 -0
- package/dist/v2/auth/factory.js +31 -0
- package/dist/v2/auth/service/baseService.d.ts +10 -0
- package/dist/v2/auth/service/baseService.js +82 -0
- package/dist/v2/auth/service/index.d.ts +3 -0
- package/dist/v2/auth/service/index.js +3 -0
- package/dist/v2/auth/service/service.d.ts +19 -0
- package/dist/v2/auth/service/service.js +162 -0
- package/dist/v2/client/builder/builder.d.ts +7 -0
- package/dist/v2/client/builder/builder.js +14 -0
- package/dist/v2/client/builder/index.d.ts +2 -0
- package/dist/v2/client/builder/index.js +2 -0
- package/dist/v2/client/client.d.ts +7 -0
- package/dist/v2/client/client.js +9 -0
- package/dist/v2/client/index.d.ts +4 -0
- package/dist/v2/client/index.js +4 -0
- package/dist/v2/client/middleware/builder.d.ts +16 -0
- package/dist/v2/client/middleware/builder.js +48 -0
- package/dist/v2/client/middleware/index.d.ts +2 -0
- package/dist/v2/client/middleware/index.js +2 -0
- package/dist/v2/client/middleware/middleware.d.ts +7 -0
- package/dist/v2/client/middleware/middleware.js +39 -0
- package/dist/v2/index.d.ts +11 -0
- package/dist/v2/index.js +7 -0
- package/dist/v2/pkg/errors/errors.d.ts +5 -0
- package/dist/v2/pkg/errors/errors.js +9 -0
- package/dist/v2/pkg/errors/index.d.ts +4 -0
- package/dist/v2/pkg/errors/index.js +2 -0
- package/dist/v2/pkg/localStorage/index.d.ts +2 -0
- package/dist/v2/pkg/localStorage/index.js +2 -0
- package/dist/v2/pkg/localStorage/localStorage.d.ts +20 -0
- package/dist/v2/pkg/localStorage/localStorage.js +34 -0
- package/dist/v2/pkg/pkce/index.d.ts +2 -0
- package/dist/v2/pkg/pkce/index.js +2 -0
- package/dist/v2/pkg/pkce/pkce.d.ts +3 -0
- package/dist/v2/pkg/pkce/pkce.js +30 -0
- package/dist/v2/pkg/types/authClient.d.ts +3 -0
- package/dist/{types.js → v2/pkg/types/authClient.js} +0 -1
- package/dist/v2/pkg/types/authService.d.ts +42 -0
- package/dist/v2/pkg/types/authService.js +1 -0
- package/dist/v2/pkg/types/index.d.ts +3 -0
- package/dist/v2/pkg/types/index.js +1 -0
- package/dist/v2/pkg/url/index.d.ts +2 -0
- package/dist/v2/pkg/url/index.js +2 -0
- package/dist/v2/pkg/url/url.d.ts +8 -0
- package/dist/v2/pkg/url/url.js +40 -0
- package/dist/v2/vue/router-guard/guard.d.ts +27 -0
- package/dist/v2/vue/router-guard/guard.js +105 -0
- package/dist/v2/vue/router-guard/index.d.ts +1 -0
- package/dist/v2/vue/router-guard/index.js +1 -0
- package/package.json +16 -9
- package/dist/client/client.d.ts +0 -2
- package/dist/client/client.js +0 -14
- package/dist/client/middleware.d.ts +0 -15
- package/dist/client/middleware.js +0 -51
- package/dist/client/storage/localStorage.d.ts +0 -8
- package/dist/client/storage/localStorage.js +0 -15
- package/dist/guard/index.d.ts +0 -11
- package/dist/guard/index.js +0 -62
- package/dist/index.d.ts +0 -26
- package/dist/index.js +0 -160
- package/dist/types.d.ts +0 -16
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Middleware as OpenAPIMiddleware } from 'openapi-fetch';
|
|
2
|
-
export declare class Middleware {
|
|
3
|
-
private app;
|
|
4
|
-
private baseUrl;
|
|
5
|
-
private redirectBaseUrl;
|
|
6
|
-
private redirectUriPrefix;
|
|
7
|
-
constructor(app: string, baseUrl: string, redirectBaseUrl: string, redirectUriPrefix?: string);
|
|
8
|
-
/**
|
|
9
|
-
* Middleware для предварительного клонирования запросов с телом.
|
|
10
|
-
* Этот клон будет использован для повторной попытки в случае 401.
|
|
11
|
-
*/
|
|
12
|
-
get RequestCloner(): OpenAPIMiddleware;
|
|
13
|
-
get AuthorizationHeaderAttacher(): OpenAPIMiddleware;
|
|
14
|
-
get TokenRefresher(): OpenAPIMiddleware;
|
|
15
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { GetAuthService } from '../index';
|
|
2
|
-
export class Middleware {
|
|
3
|
-
app;
|
|
4
|
-
baseUrl;
|
|
5
|
-
redirectBaseUrl;
|
|
6
|
-
redirectUriPrefix;
|
|
7
|
-
constructor(app, baseUrl, redirectBaseUrl, redirectUriPrefix = "") {
|
|
8
|
-
this.app = app;
|
|
9
|
-
this.baseUrl = baseUrl;
|
|
10
|
-
this.redirectBaseUrl = redirectBaseUrl;
|
|
11
|
-
this.redirectUriPrefix = redirectUriPrefix;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Middleware для предварительного клонирования запросов с телом.
|
|
15
|
-
* Этот клон будет использован для повторной попытки в случае 401.
|
|
16
|
-
*/
|
|
17
|
-
get RequestCloner() {
|
|
18
|
-
return {
|
|
19
|
-
async onRequest({ request }) {
|
|
20
|
-
// Клонируем только запросы, которые могут иметь тело
|
|
21
|
-
const methodsWithBody = ['POST', 'PUT', 'PATCH', 'DELETE'];
|
|
22
|
-
if (methodsWithBody.includes(request.method.toUpperCase())) {
|
|
23
|
-
request._clone = request.clone();
|
|
24
|
-
console.log('cloned');
|
|
25
|
-
}
|
|
26
|
-
return request;
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
get AuthorizationHeaderAttacher() {
|
|
31
|
-
const auth = GetAuthService(this.app, this.baseUrl, this.redirectBaseUrl, this.redirectUriPrefix);
|
|
32
|
-
return {
|
|
33
|
-
async onRequest({ request }) {
|
|
34
|
-
return auth.WithAuthorizationToken(request);
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
get TokenRefresher() {
|
|
39
|
-
const t = this;
|
|
40
|
-
return {
|
|
41
|
-
async onResponse({ response, request }) {
|
|
42
|
-
if (response.status !== 401 || request.url.includes('/auth/refresh')) {
|
|
43
|
-
return response;
|
|
44
|
-
}
|
|
45
|
-
const auth = GetAuthService(t.app, t.baseUrl, t.redirectBaseUrl, t.redirectUriPrefix);
|
|
46
|
-
const requestToRetry = request._clone || request;
|
|
47
|
-
return auth.RefreshAndRetry(requestToRetry, response);
|
|
48
|
-
},
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export var StorageKey;
|
|
2
|
-
(function (StorageKey) {
|
|
3
|
-
StorageKey["ACCESS_TOKEN"] = "accessToken";
|
|
4
|
-
})(StorageKey || (StorageKey = {}));
|
|
5
|
-
export class Storage {
|
|
6
|
-
static Set(key, value) {
|
|
7
|
-
localStorage.setItem(key, value);
|
|
8
|
-
}
|
|
9
|
-
static Delete(key) {
|
|
10
|
-
localStorage.removeItem(key);
|
|
11
|
-
}
|
|
12
|
-
static Get(key) {
|
|
13
|
-
return localStorage.getItem(key);
|
|
14
|
-
}
|
|
15
|
-
}
|
package/dist/guard/index.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { GetAuthService } from '../index';
|
|
2
|
-
import { Route } from '../types';
|
|
3
|
-
export declare class Guard {
|
|
4
|
-
private getAuthService;
|
|
5
|
-
private onUserRetrieve?;
|
|
6
|
-
constructor(getAuthService: () => ReturnType<typeof GetAuthService>, onUserRetrieve?: ((user: {
|
|
7
|
-
userId: string;
|
|
8
|
-
roles: string[];
|
|
9
|
-
}) => void) | undefined);
|
|
10
|
-
Auth: (roles?: string[]) => (to: Route, from: Route) => Promise<string | true>;
|
|
11
|
-
}
|
package/dist/guard/index.js
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { Storage, StorageKey } from '../client/storage/localStorage';
|
|
2
|
-
let meCache = null;
|
|
3
|
-
const ME_CACHE_TTL_MS = 15 * 1000;
|
|
4
|
-
function arrayIntercept(arr1, arr2) {
|
|
5
|
-
return arr1.filter((item) => arr2.includes(item));
|
|
6
|
-
}
|
|
7
|
-
export class Guard {
|
|
8
|
-
getAuthService;
|
|
9
|
-
onUserRetrieve;
|
|
10
|
-
constructor(getAuthService, onUserRetrieve) {
|
|
11
|
-
this.getAuthService = getAuthService;
|
|
12
|
-
this.onUserRetrieve = onUserRetrieve;
|
|
13
|
-
}
|
|
14
|
-
Auth = (roles = []) => {
|
|
15
|
-
return async (to, from) => {
|
|
16
|
-
const auth = this.getAuthService();
|
|
17
|
-
const loginRedirect = auth.GetLoginRedirectPath(to, from);
|
|
18
|
-
let token = Storage.Get(StorageKey.ACCESS_TOKEN);
|
|
19
|
-
if (!token) {
|
|
20
|
-
if (roles.length === 0)
|
|
21
|
-
return true;
|
|
22
|
-
// try to refresh
|
|
23
|
-
token = await auth.Refresh();
|
|
24
|
-
if (token) {
|
|
25
|
-
Storage.Set(StorageKey.ACCESS_TOKEN, token);
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
return loginRedirect.redirect();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
const now = Date.now();
|
|
32
|
-
if (meCache && meCache.expiresAt > now) {
|
|
33
|
-
const data = meCache.data;
|
|
34
|
-
if (arrayIntercept(data.roles, roles).length === 0) {
|
|
35
|
-
return loginRedirect.redirect();
|
|
36
|
-
}
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
const response = await auth.GetMe();
|
|
40
|
-
if (!response) {
|
|
41
|
-
console.warn('Access denied');
|
|
42
|
-
return loginRedirect.redirect();
|
|
43
|
-
}
|
|
44
|
-
meCache = { data: response, expiresAt: Date.now() + ME_CACHE_TTL_MS };
|
|
45
|
-
if (this.onUserRetrieve) {
|
|
46
|
-
this.onUserRetrieve({
|
|
47
|
-
userId: response.userId,
|
|
48
|
-
roles: response.roles,
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
if (response.roles.length === 0) {
|
|
52
|
-
console.warn('No roles found');
|
|
53
|
-
return loginRedirect.redirect();
|
|
54
|
-
}
|
|
55
|
-
if (arrayIntercept(response.roles, roles).length === 0) {
|
|
56
|
-
console.warn('Access denied');
|
|
57
|
-
return loginRedirect.redirect();
|
|
58
|
-
}
|
|
59
|
-
return true;
|
|
60
|
-
};
|
|
61
|
-
};
|
|
62
|
-
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { GetMeResponse, Route } from './types';
|
|
2
|
-
declare class AuthService {
|
|
3
|
-
private app;
|
|
4
|
-
private apiURL;
|
|
5
|
-
private redirectBaseUrl;
|
|
6
|
-
private redirectUriPrefix;
|
|
7
|
-
private refreshPromise;
|
|
8
|
-
constructor(app: string, apiURL: string, redirectBaseUrl: string, redirectUriPrefix?: string);
|
|
9
|
-
private getClient;
|
|
10
|
-
/**
|
|
11
|
-
* @description Refresh access token
|
|
12
|
-
* @returns `accessToken` -> refresh ok. `null` -> refresh failed
|
|
13
|
-
**/
|
|
14
|
-
private doRefresh;
|
|
15
|
-
withApp(app: string): this;
|
|
16
|
-
WithAuthorizationToken(request: Request, token?: string | null): Request;
|
|
17
|
-
GetLoginRedirectPath(to: Route, from?: Route): {
|
|
18
|
-
redirect: () => string;
|
|
19
|
-
};
|
|
20
|
-
GetMe(verbose?: boolean): Promise<GetMeResponse | null>;
|
|
21
|
-
Logout(): Promise<boolean>;
|
|
22
|
-
Refresh(): Promise<string | null>;
|
|
23
|
-
RefreshAndRetry(request: Request, response: Response): Promise<Response>;
|
|
24
|
-
}
|
|
25
|
-
export declare function GetAuthService(app: string, apiURL: string, redirectBaseUrl: string, redirectUriPrefix: string): AuthService;
|
|
26
|
-
export {};
|
package/dist/index.js
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import { getClient } from './client/client';
|
|
2
|
-
import { Storage, StorageKey } from './client/storage/localStorage';
|
|
3
|
-
class AuthService {
|
|
4
|
-
app;
|
|
5
|
-
apiURL;
|
|
6
|
-
redirectBaseUrl;
|
|
7
|
-
redirectUriPrefix;
|
|
8
|
-
// теперь обещание возвращает сам новый токен или null
|
|
9
|
-
refreshPromise = null;
|
|
10
|
-
constructor(app, apiURL, redirectBaseUrl, redirectUriPrefix = "") {
|
|
11
|
-
this.app = app;
|
|
12
|
-
this.apiURL = apiURL;
|
|
13
|
-
this.redirectBaseUrl = redirectBaseUrl;
|
|
14
|
-
this.redirectUriPrefix = redirectUriPrefix;
|
|
15
|
-
}
|
|
16
|
-
getClient() {
|
|
17
|
-
return getClient(this.app, this.apiURL, this.redirectBaseUrl, this.redirectUriPrefix);
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* @description Refresh access token
|
|
21
|
-
* @returns `accessToken` -> refresh ok. `null` -> refresh failed
|
|
22
|
-
**/
|
|
23
|
-
async doRefresh() {
|
|
24
|
-
const { data, error } = await this.getClient().POST('/auth/refresh');
|
|
25
|
-
if (error) {
|
|
26
|
-
console.error('Refresh error:', error);
|
|
27
|
-
Storage.Delete(StorageKey.ACCESS_TOKEN);
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
30
|
-
if (data?.accessToken) {
|
|
31
|
-
Storage.Set(StorageKey.ACCESS_TOKEN, data.accessToken);
|
|
32
|
-
return data.accessToken;
|
|
33
|
-
}
|
|
34
|
-
Storage.Delete(StorageKey.ACCESS_TOKEN);
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
withApp(app) {
|
|
38
|
-
this.app = app;
|
|
39
|
-
return this;
|
|
40
|
-
}
|
|
41
|
-
WithAuthorizationToken(request, token = null) {
|
|
42
|
-
token ??= Storage.Get(StorageKey.ACCESS_TOKEN);
|
|
43
|
-
if (token) {
|
|
44
|
-
request.headers.set('Authorization', `Bearer ${token}`);
|
|
45
|
-
}
|
|
46
|
-
return request;
|
|
47
|
-
}
|
|
48
|
-
GetLoginRedirectPath(to, from) {
|
|
49
|
-
const redirectUri = from?.query['redirect_uri'] || encodeURIComponent(to.fullPath);
|
|
50
|
-
const redirectPath = `${this.redirectBaseUrl}?redirect_uri=${this.redirectUriPrefix}${redirectUri}`;
|
|
51
|
-
return {
|
|
52
|
-
redirect: () => {
|
|
53
|
-
if (redirectPath.startsWith('http')) {
|
|
54
|
-
window.location.href = redirectPath;
|
|
55
|
-
return "";
|
|
56
|
-
}
|
|
57
|
-
return redirectPath;
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
async GetMe(verbose = false) {
|
|
62
|
-
let token = Storage.Get(StorageKey.ACCESS_TOKEN);
|
|
63
|
-
if (!token) {
|
|
64
|
-
token = await this.Refresh();
|
|
65
|
-
if (!token) {
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
const { response, data, error } = await this.getClient().GET('/auth/me', {
|
|
70
|
-
params: {
|
|
71
|
-
query: {
|
|
72
|
-
app: this.app,
|
|
73
|
-
verbose: verbose ? 'all' : 'none',
|
|
74
|
-
},
|
|
75
|
-
header: {
|
|
76
|
-
Authorization: `Bearer ${token}`,
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
if (error) {
|
|
81
|
-
console.error(error);
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
if (!data || !data.user_id) {
|
|
85
|
-
console.warn('Failed to get user info: ', data);
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
return {
|
|
89
|
-
userId: data.user_id,
|
|
90
|
-
roles: data.roles || [],
|
|
91
|
-
active: data.active || false,
|
|
92
|
-
info: !data.info ? undefined : {
|
|
93
|
-
verified: data.info.verified || false,
|
|
94
|
-
username: data.info.username,
|
|
95
|
-
email: data.info.email,
|
|
96
|
-
avatar: data.info.avatar,
|
|
97
|
-
data: data.info.data,
|
|
98
|
-
},
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
async Logout() {
|
|
102
|
-
Storage.Delete(StorageKey.ACCESS_TOKEN);
|
|
103
|
-
const { response, error } = await this.getClient().POST('/auth/logout');
|
|
104
|
-
if (error || !response.ok) {
|
|
105
|
-
console.error(error, response);
|
|
106
|
-
return false;
|
|
107
|
-
}
|
|
108
|
-
return true;
|
|
109
|
-
}
|
|
110
|
-
async Refresh() {
|
|
111
|
-
if (this.refreshPromise) {
|
|
112
|
-
return this.refreshPromise;
|
|
113
|
-
}
|
|
114
|
-
this.refreshPromise = this.doRefresh();
|
|
115
|
-
let token = null;
|
|
116
|
-
try {
|
|
117
|
-
token = await this.refreshPromise;
|
|
118
|
-
}
|
|
119
|
-
catch (e) {
|
|
120
|
-
console.error(e);
|
|
121
|
-
}
|
|
122
|
-
finally {
|
|
123
|
-
this.refreshPromise = null;
|
|
124
|
-
}
|
|
125
|
-
return token;
|
|
126
|
-
}
|
|
127
|
-
async RefreshAndRetry(request, response) {
|
|
128
|
-
if (!this.refreshPromise) {
|
|
129
|
-
this.refreshPromise = this.doRefresh();
|
|
130
|
-
}
|
|
131
|
-
let token = null;
|
|
132
|
-
try {
|
|
133
|
-
token = await this.refreshPromise;
|
|
134
|
-
}
|
|
135
|
-
catch (e) {
|
|
136
|
-
console.error(e);
|
|
137
|
-
}
|
|
138
|
-
finally {
|
|
139
|
-
this.refreshPromise = null;
|
|
140
|
-
}
|
|
141
|
-
if (!token) {
|
|
142
|
-
return response;
|
|
143
|
-
}
|
|
144
|
-
try {
|
|
145
|
-
const originalRequest = request instanceof Request ? request : new Request(request);
|
|
146
|
-
const retriedResponse = await fetch(this.WithAuthorizationToken(originalRequest.clone(), token));
|
|
147
|
-
return retriedResponse;
|
|
148
|
-
}
|
|
149
|
-
catch (e) {
|
|
150
|
-
return response;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
let auth = null;
|
|
155
|
-
export function GetAuthService(app, apiURL, redirectBaseUrl, redirectUriPrefix) {
|
|
156
|
-
if (!auth) {
|
|
157
|
-
auth = new AuthService(app, apiURL, redirectBaseUrl, redirectUriPrefix);
|
|
158
|
-
}
|
|
159
|
-
return auth.withApp(app);
|
|
160
|
-
}
|
package/dist/types.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export interface GetMeResponse {
|
|
2
|
-
roles: string[];
|
|
3
|
-
userId: string;
|
|
4
|
-
active: boolean;
|
|
5
|
-
info?: {
|
|
6
|
-
verified: boolean;
|
|
7
|
-
avatar?: string;
|
|
8
|
-
data?: Record<string, unknown>;
|
|
9
|
-
email?: string;
|
|
10
|
-
username?: string;
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
export interface Route {
|
|
14
|
-
query: Record<string, unknown>;
|
|
15
|
-
fullPath: string;
|
|
16
|
-
}
|