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.
- package/dist/AuthManager.d.ts +1 -0
- package/dist/AuthManager.js +13 -5
- package/package.json +3 -1
- package/src/AuthManager.ts +16 -8
- package/tests/AuthManager.test.ts +15 -2
package/dist/AuthManager.d.ts
CHANGED
|
@@ -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>;
|
package/dist/AuthManager.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
152
|
-
if (!decodedToken
|
|
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.
|
|
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.
|
|
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",
|
package/src/AuthManager.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
1
|
+
import axios, { AxiosResponse } from 'axios';
|
|
2
2
|
import { createHash, randomBytes } from 'crypto';
|
|
3
|
-
import
|
|
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 =
|
|
153
|
+
const decodedToken = jwtDecode(bearerToken, { complete: true })?.payload;
|
|
146
154
|
|
|
147
|
-
if (!decodedToken
|
|
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
|
-
|
|
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:
|
|
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',
|
|
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 () => {
|