@dehwyyy/auth 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.
@@ -7,8 +7,14 @@ export declare class Guards {
7
7
  private apiURL;
8
8
  private redirectBaseUrl;
9
9
  private redirectUriPrefix;
10
- constructor(app: string, apiURL: string, redirectBaseUrl: string, redirectUriPrefix?: string);
11
- private getLoginRedirectPath;
10
+ private onUserRetrieve?;
11
+ constructor(app: string, apiURL: string, redirectBaseUrl: string, redirectUriPrefix?: string, onUserRetrieve?: ((user: {
12
+ userId: string;
13
+ roles: string[];
14
+ }) => void) | undefined);
15
+ GetLoginRedirectPath(to: Route, from?: Route): {
16
+ redirect: () => string;
17
+ };
12
18
  Auth: (roles?: string[]) => (to: Route, from: Route) => Promise<string | true>;
13
19
  }
14
20
  export {};
@@ -10,48 +10,70 @@ export class Guards {
10
10
  apiURL;
11
11
  redirectBaseUrl;
12
12
  redirectUriPrefix;
13
- constructor(app, apiURL, redirectBaseUrl, redirectUriPrefix = "") {
13
+ onUserRetrieve;
14
+ constructor(app, apiURL, redirectBaseUrl, redirectUriPrefix = "", onUserRetrieve) {
14
15
  this.app = app;
15
16
  this.apiURL = apiURL;
16
17
  this.redirectBaseUrl = redirectBaseUrl;
17
18
  this.redirectUriPrefix = redirectUriPrefix;
19
+ this.onUserRetrieve = onUserRetrieve;
18
20
  }
19
- getLoginRedirectPath(to, from) {
20
- const redirectUri = from.query['redirect_uri'] || encodeURIComponent(to.fullPath);
21
+ GetLoginRedirectPath(to, from) {
22
+ const redirectUri = from?.query['redirect_uri'] || encodeURIComponent(to.fullPath);
21
23
  const redirectPath = `${this.redirectBaseUrl}?redirect_uri=${this.redirectUriPrefix}${redirectUri}`;
22
- return redirectPath;
24
+ return {
25
+ redirect: () => {
26
+ if (redirectPath.startsWith('http')) {
27
+ window.location.href = redirectPath;
28
+ return "";
29
+ }
30
+ return "";
31
+ }
32
+ };
23
33
  }
24
34
  Auth = (roles = []) => {
25
35
  return async (to, from) => {
26
- const loginRedirect = this.getLoginRedirectPath(to, from);
27
- const token = Storage.Get(StorageKey.ACCESS_TOKEN);
36
+ const loginRedirect = this.GetLoginRedirectPath(to, from);
37
+ let token = Storage.Get(StorageKey.ACCESS_TOKEN);
28
38
  if (!token) {
29
39
  if (roles.length === 0)
30
40
  return true;
31
- console.warn('Access denied');
32
- return loginRedirect;
41
+ // try to refresh
42
+ token = await GetAuthService(this.app, this.apiURL).Refresh();
43
+ if (token) {
44
+ Storage.Set(StorageKey.ACCESS_TOKEN, token);
45
+ }
46
+ else {
47
+ return loginRedirect.redirect();
48
+ }
33
49
  }
34
50
  const now = Date.now();
35
51
  if (meCache && meCache.expiresAt > now) {
36
52
  const data = meCache.data;
37
53
  if (arrayIntercept(data.roles, roles).length === 0) {
38
- return loginRedirect;
54
+ return loginRedirect.redirect();
39
55
  }
40
56
  return true;
41
57
  }
42
- const response = await GetAuthService(this.app, this.apiURL).Validate();
58
+ const response = await GetAuthService(this.app, this.apiURL).GetMe();
43
59
  if (!response) {
44
60
  console.warn('Access denied');
45
- return loginRedirect;
61
+ return loginRedirect.redirect();
46
62
  }
47
63
  meCache = { data: response, expiresAt: Date.now() + ME_CACHE_TTL_MS };
64
+ if (this.onUserRetrieve) {
65
+ this.onUserRetrieve({
66
+ userId: response.userId,
67
+ roles: response.roles,
68
+ });
69
+ }
48
70
  if (response.roles.length === 0) {
49
71
  console.warn('No roles found');
50
- return loginRedirect;
72
+ return loginRedirect.redirect();
51
73
  }
52
74
  if (arrayIntercept(response.roles, roles).length === 0) {
53
75
  console.warn('Access denied');
54
- return loginRedirect;
76
+ return loginRedirect.redirect();
55
77
  }
56
78
  return true;
57
79
  };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,14 @@
1
- interface ValidateResponse {
2
- userId: string;
1
+ interface GetMeResponse {
3
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
+ };
4
12
  }
5
13
  declare class AuthService {
6
14
  private app;
@@ -14,8 +22,10 @@ declare class AuthService {
14
22
  * @returns `accessToken` -> refresh ok. `null` -> refresh failed
15
23
  **/
16
24
  private doRefresh;
17
- Validate(): Promise<ValidateResponse | null>;
18
25
  WithAuthorizationToken(request: Request, token?: string | null): Request;
26
+ GetMe(verbose?: boolean): Promise<GetMeResponse | null>;
27
+ Logout(): Promise<boolean>;
28
+ Refresh(): Promise<string | null>;
19
29
  RefreshAndRetry(request: Request, response: Response): Promise<Response>;
20
30
  }
21
31
  export declare function GetAuthService(app: string, apiURL: string): AuthService;
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { getClient } from './client/client';
2
2
  import { Storage, StorageKey } from './client/storage/localStorage';
3
+ ;
3
4
  class AuthService {
4
5
  app;
5
6
  apiURL;
@@ -34,16 +35,26 @@ class AuthService {
34
35
  Storage.Delete(StorageKey.ACCESS_TOKEN);
35
36
  return null;
36
37
  }
37
- // Validate token
38
- async Validate() {
39
- const token = Storage.Get(StorageKey.ACCESS_TOKEN);
38
+ WithAuthorizationToken(request, token = null) {
39
+ token ??= Storage.Get(StorageKey.ACCESS_TOKEN);
40
+ if (token) {
41
+ request.headers.set('Authorization', `Bearer ${token}`);
42
+ }
43
+ return request;
44
+ }
45
+ async GetMe(verbose = false) {
46
+ let token = Storage.Get(StorageKey.ACCESS_TOKEN);
40
47
  if (!token) {
41
- return null;
48
+ token = await this.Refresh();
49
+ if (!token) {
50
+ return null;
51
+ }
42
52
  }
43
53
  const { response, data, error } = await this.getClient().GET('/auth/me', {
44
54
  params: {
45
55
  query: {
46
56
  app: this.app,
57
+ verbose: verbose ? 'all' : 'none',
47
58
  },
48
59
  header: {
49
60
  Authorization: `Bearer ${token}`,
@@ -61,14 +72,41 @@ class AuthService {
61
72
  return {
62
73
  userId: data.user_id,
63
74
  roles: data.roles || [],
75
+ active: data.active || false,
76
+ info: !data.info ? undefined : {
77
+ verified: data.info.verified || false,
78
+ username: data.info.username,
79
+ email: data.info.email,
80
+ avatar: data.info.avatar,
81
+ data: data.info.data,
82
+ },
64
83
  };
65
84
  }
66
- WithAuthorizationToken(request, token = null) {
67
- token ??= Storage.Get(StorageKey.ACCESS_TOKEN);
68
- if (token) {
69
- request.headers.set('Authorization', `Bearer ${token}`);
85
+ async Logout() {
86
+ Storage.Delete(StorageKey.ACCESS_TOKEN);
87
+ const { response, error } = await this.getClient().POST('/auth/logout');
88
+ if (error || !response.ok) {
89
+ console.error(error, response);
90
+ return false;
70
91
  }
71
- return request;
92
+ return true;
93
+ }
94
+ async Refresh() {
95
+ if (this.refreshPromise) {
96
+ return this.refreshPromise;
97
+ }
98
+ this.refreshPromise = this.doRefresh();
99
+ let token = null;
100
+ try {
101
+ token = await this.refreshPromise;
102
+ }
103
+ catch (e) {
104
+ console.error(e);
105
+ }
106
+ finally {
107
+ this.refreshPromise = null;
108
+ }
109
+ return token;
72
110
  }
73
111
  async RefreshAndRetry(request, response) {
74
112
  if (!this.refreshPromise) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dehwyyy/auth",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "private": false,
5
5
  "description": "dehwyyy auth utilities",
6
6
  "type": "module",