anzar 1.0.0 → 1.0.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/.gitlab-ci.yml ADDED
@@ -0,0 +1,23 @@
1
+ stages:
2
+ - deploy
3
+
4
+ # permissions:
5
+ # id-token: write # Required for OIDC
6
+ # contents: read
7
+
8
+ publish_npm:
9
+ stage: deploy
10
+ image: node:latest
11
+ id_tokens:
12
+ NPM_ID_TOKEN:
13
+ aud: "npm:registry.npmjs.org"
14
+ SIGSTORE_ID_TOKEN:
15
+ aud: sigstore
16
+ script:
17
+ - npm publish
18
+
19
+ # only:
20
+ # - tags
21
+
22
+ # rules:
23
+ # - if: $CI_COMMIT_TAG
package/Makefile ADDED
@@ -0,0 +1,8 @@
1
+ clean:
2
+ rm -rf dist
3
+ install:
4
+ pnpm i
5
+ publish:
6
+ pnpm version patch
7
+ # pnpm build
8
+ git push
package/package.json CHANGED
@@ -1,22 +1,26 @@
1
1
  {
2
- "name": "anzar",
3
- "version": "1.0.0",
4
- "description": "Anzar SDK",
5
- "main": "index.ts",
6
- "keywords": [],
7
- "repository": {
8
- "type": "git",
9
- "url": "git+https://gitlab.com/anzar_software/typescript-sdk.git"
10
- },
11
- "author": "Hakou Guelfen",
12
- "license": "GPL",
13
- "dependencies": {
14
- "@types/node": "^25.0.3",
15
- "axios": "^1.13.2",
16
- "yaml": "^2.8.2",
17
- "zod": "^4.2.1"
18
- },
19
- "scripts": {
20
- "test": "echo \"Error: no test specified\" && exit 1"
21
- }
22
- }
2
+ "name": "anzar",
3
+ "version": "1.0.24",
4
+ "description": "Anzar SDK",
5
+ "main": "index.ts",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "keywords": [],
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://gitlab.com/anzar_software/typescript-sdk.git"
13
+ },
14
+ "author": "Hakou Guelfen",
15
+ "license": "GPLV3",
16
+ "packageManager": "pnpm@10.28.2",
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "dependencies": {
21
+ "@types/node": "^25.0.3",
22
+ "axios": "^1.13.2",
23
+ "yaml": "^2.8.2",
24
+ "zod": "^4.2.1"
25
+ }
26
+ }
@@ -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
  }