supaapps-auth 1.4.0 → 1.4.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.
@@ -16,6 +16,7 @@ export declare class AuthManager {
16
16
  getLoginWithGoogleUri(): string;
17
17
  isLoggedIn(): Promise<boolean>;
18
18
  getAccessToken(): Promise<string>;
19
+ private saveTokens;
19
20
  loginUsingPkce(code: string): Promise<void>;
20
21
  logout(): Promise<void>;
21
22
  static validateToken(authServer: string, bearerToken: string): Promise<boolean>;
@@ -56,6 +56,8 @@ class AuthManager {
56
56
  });
57
57
  localStorage.setItem('refresh_token', response.data.refresh_token);
58
58
  localStorage.setItem('access_token', response.data.access_token);
59
+ const user = (0, jsonwebtoken_1.decode)(response.data.access_token);
60
+ localStorage.setItem('user', JSON.stringify(user));
59
61
  return response.data.access_token;
60
62
  }
61
63
  catch (error) {
@@ -105,6 +107,12 @@ class AuthManager {
105
107
  return this.checkAccessToken();
106
108
  });
107
109
  }
110
+ saveTokens(response) {
111
+ localStorage.setItem('access_token', response.data.access_token);
112
+ localStorage.setItem('refresh_token', response.data.refresh_token);
113
+ const user = (0, jsonwebtoken_1.decode)(response.data.access_token);
114
+ localStorage.setItem('user', JSON.stringify(user));
115
+ }
108
116
  loginUsingPkce(code) {
109
117
  return __awaiter(this, void 0, void 0, function* () {
110
118
  try {
@@ -118,8 +126,7 @@ class AuthManager {
118
126
  redirect_uri: this.redirectUri,
119
127
  code_verifier: codeVerifier,
120
128
  });
121
- localStorage.setItem('access_token', response.data.access_token);
122
- localStorage.setItem('refresh_token', response.data.refresh_token);
129
+ this.saveTokens(response);
123
130
  }
124
131
  finally {
125
132
  localStorage.removeItem('codeVerifier');
@@ -147,14 +154,15 @@ class AuthManager {
147
154
  static validateToken(authServer, bearerToken) {
148
155
  var _a;
149
156
  return __awaiter(this, void 0, void 0, function* () {
157
+ // @todo tests missing for this static validation
150
158
  try {
151
- const decodedToken = (_a = jsonwebtoken_1.default.decode(bearerToken, { complete: true })) === null || _a === void 0 ? void 0 : _a.payload;
152
- if (!decodedToken || decodedToken.exp < Date.now() / 1000) {
159
+ const decodedToken = (_a = (0, jsonwebtoken_1.decode)(bearerToken, { complete: true })) === null || _a === void 0 ? void 0 : _a.payload;
160
+ if (!decodedToken) {
153
161
  return false;
154
162
  }
155
163
  const { data: publicKey } = yield axios_1.default.get(`${authServer}public/public_key`);
156
164
  const { data: algo } = yield axios_1.default.get(`${authServer}public/algo`);
157
- jsonwebtoken_1.default.verify(bearerToken, publicKey, { algorithms: [algo] });
165
+ (0, jsonwebtoken_1.verify)(bearerToken, publicKey, { algorithms: [algo] });
158
166
  const { data: revokedIds } = yield axios_1.default.get(`${authServer}public/revoked_ids`);
159
167
  return !revokedIds.includes(decodedToken['id']);
160
168
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "supaapps-auth",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -16,7 +16,9 @@
16
16
  "jsonwebtoken": "^9.0.2"
17
17
  },
18
18
  "devDependencies": {
19
+ "@types/axios": "^0.14.0",
19
20
  "@types/jest": "^29.5.12",
21
+ "@types/jsonwebtoken": "^9.0.6",
20
22
  "@types/node": "^20.11.10",
21
23
  "axios-mock-adapter": "^1.22.0",
22
24
  "jest": "^29.7.0",
@@ -1,6 +1,6 @@
1
- import axios from 'axios';
1
+ import axios, { AxiosResponse } from 'axios';
2
2
  import { createHash, randomBytes } from 'crypto';
3
- import jwt from 'jsonwebtoken'; // Ensure jsonwebtoken is correctly imported
3
+ import {decode as jwtDecode, verify as jwtVerify} from 'jsonwebtoken'; // Ensure jsonwebtoken is correctly imported
4
4
 
5
5
  export class AuthManager {
6
6
  private static instance: AuthManager | null = null;
@@ -58,6 +58,8 @@ export class AuthManager {
58
58
 
59
59
  localStorage.setItem('refresh_token', response.data.refresh_token);
60
60
  localStorage.setItem('access_token', response.data.access_token);
61
+ const user = jwtDecode(response.data.access_token);
62
+ localStorage.setItem('user', JSON.stringify(user));
61
63
  return response.data.access_token;
62
64
  } catch (error) {
63
65
  console.error(`Refresh token error, logging out: ${error}`);
@@ -103,6 +105,13 @@ export class AuthManager {
103
105
  return this.checkAccessToken();
104
106
  }
105
107
 
108
+ private saveTokens(response: AxiosResponse): void {
109
+ localStorage.setItem('access_token', response.data.access_token);
110
+ localStorage.setItem('refresh_token', response.data.refresh_token);
111
+ const user = jwtDecode(response.data.access_token);
112
+ localStorage.setItem('user', JSON.stringify(user));
113
+ }
114
+
106
115
  public async loginUsingPkce(code: string): Promise<void> {
107
116
  try {
108
117
  const codeVerifier = localStorage.getItem('codeVerifier');
@@ -116,9 +125,7 @@ export class AuthManager {
116
125
  redirect_uri: this.redirectUri,
117
126
  code_verifier: codeVerifier,
118
127
  });
119
-
120
- localStorage.setItem('access_token', response.data.access_token);
121
- localStorage.setItem('refresh_token', response.data.refresh_token);
128
+ this.saveTokens(response);
122
129
  } finally {
123
130
  localStorage.removeItem('codeVerifier');
124
131
  localStorage.removeItem('codeChallenge');
@@ -141,17 +148,18 @@ export class AuthManager {
141
148
  }
142
149
 
143
150
  public static async validateToken(authServer: string, bearerToken: string): Promise<boolean> {
151
+ // @todo tests missing for this static validation
144
152
  try {
145
- const decodedToken = jwt.decode(bearerToken, { complete: true })?.payload;
153
+ const decodedToken = jwtDecode(bearerToken, { complete: true })?.payload;
146
154
 
147
- if (!decodedToken || decodedToken.exp < Date.now() / 1000) {
155
+ if (!decodedToken) {
148
156
  return false;
149
157
  }
150
158
 
151
159
  const { data: publicKey } = await axios.get(`${authServer}public/public_key`);
152
160
  const { data: algo } = await axios.get(`${authServer}public/algo`);
153
161
 
154
- jwt.verify(bearerToken, publicKey, { algorithms: [algo] });
162
+ jwtVerify(bearerToken, publicKey, { algorithms: [algo] });
155
163
 
156
164
  const { data: revokedIds } = await axios.get(`${authServer}public/revoked_ids`);
157
165
  return !revokedIds.includes(decodedToken['id']);
@@ -1,6 +1,7 @@
1
1
  import axios from 'axios';
2
2
  import MockAdapter from 'axios-mock-adapter';
3
3
  import { AuthManager } from '../src/AuthManager';
4
+ import { basename } from 'path';
4
5
 
5
6
  const mock = new MockAdapter(axios);
6
7
 
@@ -77,8 +78,18 @@ describe('AuthManager Tests', () => {
77
78
 
78
79
  it('logs in using PKCE and updates local storage', async () => {
79
80
  localStorage.setItem('codeVerifier', 'mockCodeVerifier');
81
+ /*
82
+ {
83
+ "sub": "1234567890",
84
+ "name": "John Doe",
85
+ "iat": 1516239022
86
+ }
87
+ */
88
+ const accessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
89
+
90
+
80
91
  mock.onPost('http://auth-server.com/auth/pkce_exchange').reply(200, {
81
- access_token: 'validAccessToken',
92
+ access_token: accessToken,
82
93
  refresh_token: 'validRefreshToken'
83
94
  });
84
95
 
@@ -86,8 +97,10 @@ describe('AuthManager Tests', () => {
86
97
  const manager = AuthManager.initialize('http://auth-server.com/', 'example-realm', 'http://myapp.com/callback', loginCallback);
87
98
  await manager.loginUsingPkce('mockCode');
88
99
 
89
- expect(localStorage.setItem).toHaveBeenCalledWith('access_token', 'validAccessToken');
100
+ expect(localStorage.setItem).toHaveBeenCalledWith('access_token', accessToken);
90
101
  expect(localStorage.setItem).toHaveBeenCalledWith('refresh_token', 'validRefreshToken');
102
+ const userSub = JSON.parse(localStorage.getItem('user') ?? '').sub;
103
+ expect(userSub).toEqual('1234567890');
91
104
  });
92
105
 
93
106
  it('logs out and clears local storage', async () => {