anzar 1.0.0 → 1.0.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anzar",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Anzar SDK",
5
5
  "main": "index.ts",
6
6
  "keywords": [],
@@ -1,16 +1,43 @@
1
- import type { AxiosInstance } from "axios";
2
- import { TokenType } from "../types/token";
1
+ import type {
2
+ AxiosError,
3
+ AxiosInstance,
4
+ InternalAxiosRequestConfig,
5
+ } from "axios";
6
+ import type { AuthResponse } from "../types/auth";
7
+ import { type Token, TokenType } from "../types/token";
8
+
9
+ const ENDPOINTS = new Map([
10
+ ["/auth/login", null],
11
+ ["/auth/register", null],
12
+ ["/auth/refreshToken", TokenType.RefreshToken],
13
+ ["/auth/logout", TokenType.RefreshToken],
14
+ ]);
15
+
16
+ const endpointConfig: Record<string, TokenType | null> = {
17
+ "/auth/login": null,
18
+ "/auth/register": null,
19
+ "/auth/refreshToken": TokenType.RefreshToken,
20
+ "/auth/logout": TokenType.RefreshToken,
21
+ };
3
22
 
4
23
  export class JwtInterceptor {
5
- apply(axios: AxiosInstance) {
6
- // your logic
7
- axios.interceptors.request.use(
24
+ // TODO add AnzarConfig as an arg to apply
25
+ apply(axiosInstance: AxiosInstance) {
26
+ function _extractTokenFromCache(tokenType: TokenType): Token | null {
27
+ const token = localStorage.getItem(tokenType.toString());
28
+
29
+ return token ? ({ value: token, tokenType } as Token) : null;
30
+ }
31
+
32
+ axiosInstance.interceptors.request.use(
8
33
  (config) => {
9
- const accessToken = localStorage.getItem(
10
- TokenType.AccessToken.toString(),
11
- );
12
- if (accessToken) {
13
- config.headers.Authorization = `Bearer ${accessToken}`;
34
+ const url = config.url;
35
+ if (!url) return config;
36
+ const tokenType = endpointConfig[url] ?? TokenType.AccessToken;
37
+ const token = tokenType ? _extractTokenFromCache(tokenType) : null;
38
+
39
+ if (token) {
40
+ config.headers.Authorization = `Bearer ${token}`;
14
41
  }
15
42
 
16
43
  return config;
@@ -21,8 +48,85 @@ export class JwtInterceptor {
21
48
  },
22
49
  );
23
50
 
24
- axios.interceptors.response.use((response) => {
25
- return response;
26
- });
51
+ axiosInstance.interceptors.response.use(
52
+ (response) => {
53
+ const url = response.config.url;
54
+ if (!url) return response;
55
+
56
+ if (url === "/auth/logout") {
57
+ localStorage.removeItem(TokenType.AccessToken.toString());
58
+ localStorage.removeItem(TokenType.RefreshToken.toString());
59
+ return response;
60
+ }
61
+
62
+ const value = ENDPOINTS.get(url);
63
+ const token_type = value === undefined ? TokenType.AccessToken : value;
64
+
65
+ if (token_type === TokenType.AccessToken) {
66
+ return response;
67
+ }
68
+
69
+ const auth_response: AuthResponse = response.data;
70
+
71
+ if (auth_response.tokens) {
72
+ localStorage.setItem(
73
+ TokenType.AccessToken.toString(),
74
+ auth_response.tokens.access,
75
+ );
76
+ localStorage.setItem(
77
+ TokenType.RefreshToken.toString(),
78
+ auth_response.tokens.refresh,
79
+ );
80
+ }
81
+
82
+ return response;
83
+ },
84
+ async (error: AxiosError) => {
85
+ const originalRequest = error.config as InternalAxiosRequestConfig & {
86
+ _retry?: boolean;
87
+ };
88
+
89
+ // const value = ENDPOINTS.get(error.request.url);
90
+ // const token_type = value === undefined ? TokenType.AccessToken : value;
91
+ // if (error.status === 401 && token_type === TokenType.AccessToken) {
92
+
93
+ if (error.response?.status === 401 && !originalRequest._retry) {
94
+ originalRequest._retry = true;
95
+
96
+ try {
97
+ const refreshToken = localStorage.getItem(
98
+ TokenType.RefreshToken.toString(),
99
+ );
100
+ const response = await axiosInstance.post(
101
+ "/auth/refreshToken",
102
+ {},
103
+ { headers: { authorization: `Bearer ${refreshToken}` } },
104
+ );
105
+
106
+ const auth_response: AuthResponse = response.data;
107
+ if (auth_response.tokens) {
108
+ localStorage.setItem(
109
+ TokenType.AccessToken.toString(),
110
+ auth_response.tokens.access,
111
+ );
112
+ localStorage.setItem(
113
+ TokenType.RefreshToken.toString(),
114
+ auth_response.tokens.refresh,
115
+ );
116
+ }
117
+
118
+ // Retry original request with new token
119
+ originalRequest.headers.Authorization = `Bearer ${auth_response.tokens?.access}`;
120
+ return axiosInstance(originalRequest);
121
+ } catch (e) {
122
+ localStorage.clear();
123
+ window.location.href = "/";
124
+ return Promise.reject(e);
125
+ }
126
+ }
127
+
128
+ return Promise.reject(error);
129
+ },
130
+ );
27
131
  }
28
132
  }