@soapjs/soap-auth 0.1.1 → 0.2.0
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/README.md +475 -8
- package/build/factories/http-auth-strategy.factory.js +1 -1
- package/build/factories/index.d.ts +3 -0
- package/build/factories/index.js +19 -0
- package/build/index.d.ts +4 -25
- package/build/index.js +4 -25
- package/build/session/index.d.ts +3 -0
- package/build/session/index.js +19 -0
- package/build/soap-auth.d.ts +9 -9
- package/build/soap-auth.js +64 -34
- package/build/strategies/api-key/api-key.strategy.d.ts +4 -3
- package/build/strategies/api-key/api-key.strategy.js +9 -6
- package/build/strategies/api-key/api-key.types.d.ts +2 -4
- package/build/strategies/base-auth.strategy.d.ts +4 -3
- package/build/strategies/base-auth.strategy.js +18 -2
- package/build/strategies/basic/basic.strategy.d.ts +5 -11
- package/build/strategies/basic/basic.strategy.js +14 -19
- package/build/strategies/basic/basic.types.d.ts +2 -2
- package/build/strategies/{credential-based-auth.strategy.d.ts → credential-auth.strategy.d.ts} +15 -12
- package/build/strategies/{credential-based-auth.strategy.js → credential-auth.strategy.js} +95 -46
- package/build/strategies/index.d.ts +16 -0
- package/build/strategies/index.js +32 -0
- package/build/strategies/jwt/jwt.strategy.d.ts +17 -2
- package/build/strategies/jwt/jwt.strategy.js +118 -57
- package/build/strategies/jwt/jwt.tools.d.ts +7 -3
- package/build/strategies/jwt/jwt.tools.js +80 -41
- package/build/strategies/jwt/jwt.types.d.ts +3 -27
- package/build/strategies/local/local.strategy.d.ts +3 -9
- package/build/strategies/local/local.strategy.js +7 -58
- package/build/strategies/local/local.types.d.ts +2 -2
- package/build/strategies/oauth2/oauth2.strategy.d.ts +21 -7
- package/build/strategies/oauth2/oauth2.strategy.js +158 -49
- package/build/strategies/oauth2/oauth2.types.d.ts +8 -16
- package/build/strategies/token-auth.strategy.d.ts +25 -0
- package/build/strategies/token-auth.strategy.js +78 -0
- package/build/tools/index.d.ts +3 -0
- package/build/tools/index.js +19 -0
- package/build/types.d.ts +87 -57
- package/package.json +1 -1
- package/build/strategies/token-based-auth.strategy.d.ts +0 -25
- package/build/strategies/token-based-auth.strategy.js +0 -130
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.CredentialAuthStrategy = void 0;
|
|
4
4
|
const errors_1 = require("../errors");
|
|
5
5
|
const base_auth_strategy_1 = require("./base-auth.strategy");
|
|
6
|
-
class
|
|
6
|
+
class CredentialAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy {
|
|
7
7
|
config;
|
|
8
8
|
session;
|
|
9
9
|
logger;
|
|
@@ -13,34 +13,73 @@ class CredentialBasedAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy
|
|
|
13
13
|
this.session = session;
|
|
14
14
|
this.logger = logger;
|
|
15
15
|
}
|
|
16
|
+
async storeUserSession(user, context) {
|
|
17
|
+
if (!this.session || !this.config.session) {
|
|
18
|
+
this.logger?.info("Session management is not configured. Skipping session storage.");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
let sessionId = this.config.session.getSessionId?.(context);
|
|
22
|
+
if (!sessionId) {
|
|
23
|
+
sessionId = this.config.session.generateSessionId
|
|
24
|
+
? this.config.session.generateSessionId(user, context)
|
|
25
|
+
: `sid-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
26
|
+
}
|
|
27
|
+
const sessionData = this.config.session.createSessionData
|
|
28
|
+
? this.config.session.createSessionData(user, context)
|
|
29
|
+
: { user };
|
|
30
|
+
if (this.config.session.store) {
|
|
31
|
+
await this.config.session.store.setSession(sessionId, sessionData);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
await this.session.set(sessionId, sessionData);
|
|
35
|
+
}
|
|
36
|
+
this.config.session.embedSessionId?.(context, sessionId);
|
|
37
|
+
this.logger?.info(`Stored user session with ID: ${sessionId}`);
|
|
38
|
+
}
|
|
39
|
+
async handleAuthenticationError(error, context) {
|
|
40
|
+
this.logger?.error("Authentication failed:", error);
|
|
41
|
+
await this.onFailure("login", { context, error });
|
|
42
|
+
throw new errors_1.AuthError(error, "Authentication failed.");
|
|
43
|
+
}
|
|
44
|
+
async preAuthChecks(identifier) {
|
|
45
|
+
await this.isAccountLocked(identifier);
|
|
46
|
+
await this.checkFailedAttempts(identifier);
|
|
47
|
+
await this.checkRateLimit(identifier);
|
|
48
|
+
await this.checkPasswordExpiry(identifier);
|
|
49
|
+
}
|
|
50
|
+
async handleFailedLogin(identifier) {
|
|
51
|
+
await this.config.failedAttempts.incrementFailedAttempts?.(identifier);
|
|
52
|
+
}
|
|
53
|
+
async handleSuccessfulLogin(identifier) {
|
|
54
|
+
await this.config.failedAttempts.resetFailedAttempts?.(identifier);
|
|
55
|
+
}
|
|
56
|
+
async finalizeAuthentication(user, context) {
|
|
57
|
+
await this.checkMfa(user, context);
|
|
58
|
+
await this.isAuthorized(user);
|
|
59
|
+
await this.storeUserSession(user, context);
|
|
60
|
+
}
|
|
16
61
|
async authenticate(context) {
|
|
17
62
|
try {
|
|
18
63
|
const credentials = await this.extractCredentials(context);
|
|
19
64
|
if (!credentials)
|
|
20
65
|
throw new errors_1.MissingCredentialsError();
|
|
21
|
-
await this.
|
|
22
|
-
await this.
|
|
23
|
-
await this.checkRateLimit(credentials.identifier);
|
|
24
|
-
await this.checkPasswordExpiry(credentials.identifier);
|
|
25
|
-
const valid = await this.verifyCredentials(credentials);
|
|
66
|
+
await this.preAuthChecks(credentials.identifier);
|
|
67
|
+
const valid = await this.verifyCredentials(credentials.identifier, credentials.password);
|
|
26
68
|
if (!valid) {
|
|
27
|
-
await this.
|
|
69
|
+
await this.handleFailedLogin(credentials.identifier);
|
|
28
70
|
throw new errors_1.InvalidCredentialsError();
|
|
29
71
|
}
|
|
30
|
-
await this.
|
|
31
|
-
const user = await this.retrieveUser(credentials);
|
|
72
|
+
await this.handleSuccessfulLogin(credentials.identifier);
|
|
73
|
+
const user = await this.retrieveUser(credentials.identifier);
|
|
32
74
|
if (!user)
|
|
33
75
|
throw new errors_1.UserNotFoundError();
|
|
34
|
-
await this.
|
|
35
|
-
|
|
36
|
-
await this.handleSession(user, context);
|
|
76
|
+
await this.finalizeAuthentication(user, context);
|
|
77
|
+
this.auditLoginAttempt(credentials.identifier, true, context);
|
|
37
78
|
return { user };
|
|
38
79
|
}
|
|
39
80
|
catch (e) {
|
|
40
|
-
|
|
41
|
-
this.
|
|
42
|
-
await this.config.logout.onFailure?.({ context, error: error });
|
|
43
|
-
throw error;
|
|
81
|
+
this.auditLoginAttempt(null, false, context);
|
|
82
|
+
return this.handleAuthenticationError(e, context);
|
|
44
83
|
}
|
|
45
84
|
}
|
|
46
85
|
async handleSession(user, context) {
|
|
@@ -53,78 +92,87 @@ class CredentialBasedAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy
|
|
|
53
92
|
try {
|
|
54
93
|
if (this.session) {
|
|
55
94
|
const sessionId = this.session.getSessionId?.(context);
|
|
56
|
-
if (!sessionId)
|
|
95
|
+
if (!sessionId)
|
|
57
96
|
throw new Error("Session ID is missing in the context.");
|
|
58
|
-
}
|
|
59
97
|
await this.session.destroy(sessionId);
|
|
60
|
-
this.logger
|
|
98
|
+
this.logger?.info(`Session destroyed: ${sessionId}`);
|
|
61
99
|
}
|
|
62
|
-
await this.
|
|
63
|
-
this.logger.info(`User logged out successfully.`);
|
|
100
|
+
await this.onSuccess("logout", context);
|
|
64
101
|
}
|
|
65
102
|
catch (e) {
|
|
66
103
|
const error = new errors_1.AuthError(e, "Logout process failed.");
|
|
67
|
-
this.logger
|
|
68
|
-
await this.
|
|
104
|
+
this.logger?.error("Error during logout:", error);
|
|
105
|
+
await this.onFailure("logout", { context, error });
|
|
69
106
|
throw error;
|
|
70
107
|
}
|
|
71
108
|
}
|
|
72
109
|
async requestPasswordReset(identifier, email) {
|
|
73
110
|
try {
|
|
74
|
-
if (!this.config.
|
|
111
|
+
if (!this.config?.passwordPolicy.generateResetToken) {
|
|
75
112
|
throw new Error("Password reset token generation is not configured.");
|
|
76
113
|
}
|
|
77
|
-
const token = await this.config.
|
|
114
|
+
const token = await this.config.passwordPolicy.generateResetToken(identifier);
|
|
78
115
|
if (email) {
|
|
79
|
-
await this.config.
|
|
116
|
+
await this.config.passwordPolicy.sendResetEmail?.(email, token);
|
|
80
117
|
}
|
|
81
|
-
await this.
|
|
118
|
+
await this.onSuccess("request_password_reset", { identifier });
|
|
82
119
|
this.logger.info(`Password reset requested for identifier: ${identifier}`);
|
|
83
120
|
}
|
|
84
121
|
catch (e) {
|
|
85
122
|
const error = new errors_1.AuthError(e, "Password reset request error.");
|
|
86
123
|
this.logger.error("Password reset request error:", e);
|
|
87
|
-
await this.
|
|
124
|
+
await this.onFailure("request_password_reset", {
|
|
125
|
+
identifier,
|
|
126
|
+
error: e,
|
|
127
|
+
});
|
|
88
128
|
throw error;
|
|
89
129
|
}
|
|
90
130
|
}
|
|
91
131
|
async resetPassword(identifier, token, newPassword) {
|
|
92
132
|
try {
|
|
93
|
-
if (!this.config.
|
|
133
|
+
if (!this.config.passwordPolicy?.validateResetToken) {
|
|
94
134
|
throw new Error("Password reset token validation is not configured.");
|
|
95
135
|
}
|
|
96
|
-
const isValid = await this.config.
|
|
136
|
+
const isValid = await this.config.passwordPolicy.validateResetToken(token);
|
|
97
137
|
if (!isValid) {
|
|
98
138
|
throw new Error("Invalid or expired reset token.");
|
|
99
139
|
}
|
|
100
|
-
await this.config.
|
|
101
|
-
await this.
|
|
140
|
+
await this.config.passwordPolicy.updatePassword(identifier, newPassword);
|
|
141
|
+
await this.onSuccess("password_reset", { identifier });
|
|
102
142
|
this.logger.info(`Password successfully reset for identifier: ${identifier}`);
|
|
143
|
+
this.auditPasswordChange(identifier);
|
|
103
144
|
}
|
|
104
145
|
catch (e) {
|
|
105
146
|
const error = new errors_1.AuthError(e, "Password reset error");
|
|
106
147
|
this.logger.error("Password reset error:", e);
|
|
107
|
-
await this.
|
|
148
|
+
await this.onFailure("password_reset", {
|
|
149
|
+
identifier,
|
|
150
|
+
error: e,
|
|
151
|
+
});
|
|
108
152
|
throw error;
|
|
109
153
|
}
|
|
110
154
|
}
|
|
111
155
|
async changePassword(identifier, oldPassword, newPassword) {
|
|
112
156
|
try {
|
|
113
|
-
if (!this.config.
|
|
157
|
+
if (!this.config.credentials.verifyCredentials) {
|
|
114
158
|
throw new Error("Credential verification is not configured.");
|
|
115
159
|
}
|
|
116
|
-
const isAuthenticated = await this.config.
|
|
160
|
+
const isAuthenticated = await this.config.credentials.verifyCredentials(identifier, oldPassword);
|
|
117
161
|
if (!isAuthenticated) {
|
|
118
162
|
throw new errors_1.InvalidCredentialsError();
|
|
119
163
|
}
|
|
120
|
-
await this.config.
|
|
121
|
-
await this.
|
|
164
|
+
await this.config.passwordPolicy?.updatePassword?.(identifier, newPassword);
|
|
165
|
+
await this.onSuccess("change_password", { identifier });
|
|
122
166
|
this.logger.info(`Password changed successfully for identifier: ${identifier}`);
|
|
167
|
+
this.auditPasswordChange(identifier);
|
|
123
168
|
}
|
|
124
169
|
catch (e) {
|
|
125
170
|
const error = new errors_1.AuthError(e, "Change password error");
|
|
126
171
|
this.logger.error("Change password error:", e);
|
|
127
|
-
await this.
|
|
172
|
+
await this.onFailure("change_password", {
|
|
173
|
+
identifier,
|
|
174
|
+
error: e,
|
|
175
|
+
});
|
|
128
176
|
throw error;
|
|
129
177
|
}
|
|
130
178
|
}
|
|
@@ -140,7 +188,8 @@ class CredentialBasedAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy
|
|
|
140
188
|
async checkFailedAttempts(identifier) {
|
|
141
189
|
try {
|
|
142
190
|
if (this.config.security?.maxFailedLoginAttempts) {
|
|
143
|
-
const failedAttempts = (await this.config.
|
|
191
|
+
const failedAttempts = (await this.config.failedAttempts.getFailedAttempts?.(identifier)) ||
|
|
192
|
+
0;
|
|
144
193
|
if (failedAttempts >= this.config.security.maxFailedLoginAttempts) {
|
|
145
194
|
this.logger.warn(`User ${identifier} is temporarily locked out.`);
|
|
146
195
|
throw new errors_1.AccountLockedError();
|
|
@@ -151,8 +200,8 @@ class CredentialBasedAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy
|
|
|
151
200
|
this.logger.error("Check failed attempts:", e);
|
|
152
201
|
}
|
|
153
202
|
}
|
|
154
|
-
async isAccountLocked(account
|
|
155
|
-
if (await this.config.lock.isAccountLocked?.(account
|
|
203
|
+
async isAccountLocked(account) {
|
|
204
|
+
if (await this.config.lock.isAccountLocked?.(account)) {
|
|
156
205
|
throw new errors_1.AccountLockedError();
|
|
157
206
|
}
|
|
158
207
|
if (typeof account === "string" && this.config.security?.lockoutDuration) {
|
|
@@ -172,9 +221,9 @@ class CredentialBasedAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy
|
|
|
172
221
|
return false;
|
|
173
222
|
}
|
|
174
223
|
async incrementFailedAttempts(account) {
|
|
175
|
-
if (this.config.
|
|
176
|
-
await this.config.
|
|
177
|
-
const failedAttempts = (await this.config.
|
|
224
|
+
if (this.config.failedAttempts.incrementFailedAttempts) {
|
|
225
|
+
await this.config.failedAttempts.incrementFailedAttempts(account);
|
|
226
|
+
const failedAttempts = (await this.config.failedAttempts.getFailedAttempts?.(account)) || 0;
|
|
178
227
|
if (this.config.security?.maxFailedLoginAttempts &&
|
|
179
228
|
failedAttempts >= this.config.security.maxFailedLoginAttempts) {
|
|
180
229
|
const lockoutKey = `lockout:${account}`;
|
|
@@ -202,4 +251,4 @@ class CredentialBasedAuthStrategy extends base_auth_strategy_1.BaseAuthStrategy
|
|
|
202
251
|
}
|
|
203
252
|
}
|
|
204
253
|
}
|
|
205
|
-
exports.
|
|
254
|
+
exports.CredentialAuthStrategy = CredentialAuthStrategy;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export * from "./api-key/api-key.errors";
|
|
2
|
+
export * from "./api-key/api-key.strategy";
|
|
3
|
+
export * from "./api-key/api-key.types";
|
|
4
|
+
export * from "./base-auth.strategy";
|
|
5
|
+
export * from "./basic/basic.strategy";
|
|
6
|
+
export * from "./basic/basic.types";
|
|
7
|
+
export * from "./credential-auth.strategy";
|
|
8
|
+
export * from "./jwt/jwt.strategy";
|
|
9
|
+
export * from "./jwt/jwt.tools";
|
|
10
|
+
export * from "./jwt/jwt.types";
|
|
11
|
+
export * from "./local/local.strategy";
|
|
12
|
+
export * from "./local/local.types";
|
|
13
|
+
export * from "./oauth2/oauth2.strategy";
|
|
14
|
+
export * from "./oauth2/oauth2.tools";
|
|
15
|
+
export * from "./oauth2/oauth2.types";
|
|
16
|
+
export * from "./token-auth.strategy";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./api-key/api-key.errors"), exports);
|
|
18
|
+
__exportStar(require("./api-key/api-key.strategy"), exports);
|
|
19
|
+
__exportStar(require("./api-key/api-key.types"), exports);
|
|
20
|
+
__exportStar(require("./base-auth.strategy"), exports);
|
|
21
|
+
__exportStar(require("./basic/basic.strategy"), exports);
|
|
22
|
+
__exportStar(require("./basic/basic.types"), exports);
|
|
23
|
+
__exportStar(require("./credential-auth.strategy"), exports);
|
|
24
|
+
__exportStar(require("./jwt/jwt.strategy"), exports);
|
|
25
|
+
__exportStar(require("./jwt/jwt.tools"), exports);
|
|
26
|
+
__exportStar(require("./jwt/jwt.types"), exports);
|
|
27
|
+
__exportStar(require("./local/local.strategy"), exports);
|
|
28
|
+
__exportStar(require("./local/local.types"), exports);
|
|
29
|
+
__exportStar(require("./oauth2/oauth2.strategy"), exports);
|
|
30
|
+
__exportStar(require("./oauth2/oauth2.tools"), exports);
|
|
31
|
+
__exportStar(require("./oauth2/oauth2.types"), exports);
|
|
32
|
+
__exportStar(require("./token-auth.strategy"), exports);
|
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
import * as Soap from "@soapjs/soap";
|
|
2
|
-
import {
|
|
2
|
+
import { TokenAuthStrategy } from "../token-auth.strategy";
|
|
3
3
|
import { JwtConfig } from "./jwt.types";
|
|
4
4
|
import { SessionHandler } from "../../session/session-handler";
|
|
5
|
-
|
|
5
|
+
import { TokenConfig } from "../../types";
|
|
6
|
+
export declare class JwtStrategy<TContext = unknown, TUser = unknown> extends TokenAuthStrategy<TContext, TUser> {
|
|
6
7
|
protected config: JwtConfig<TContext, TUser>;
|
|
7
8
|
protected session?: SessionHandler;
|
|
8
9
|
protected logger?: Soap.Logger;
|
|
10
|
+
protected accessTokenConfig: TokenConfig<TContext>;
|
|
11
|
+
protected refreshTokenConfig: TokenConfig<TContext>;
|
|
9
12
|
constructor(config: JwtConfig<TContext, TUser>, session?: SessionHandler, logger?: Soap.Logger);
|
|
13
|
+
protected invalidateRefreshToken(token: string): Promise<void>;
|
|
14
|
+
protected verifyAccessToken(token: string): Promise<any>;
|
|
15
|
+
protected verifyRefreshToken(token: string): Promise<any>;
|
|
16
|
+
protected generateAccessToken(payload: any): Promise<string>;
|
|
17
|
+
protected generateRefreshToken(payload: any): Promise<string>;
|
|
18
|
+
protected storeAccessToken(token: string, context: TContext): Promise<void>;
|
|
19
|
+
protected storeRefreshToken(token: string, context: TContext): Promise<void>;
|
|
20
|
+
protected embedAccessToken(token: string, context: TContext): void;
|
|
21
|
+
protected embedRefreshToken(token: string, context: TContext): void;
|
|
22
|
+
protected retrieveAccessToken(context: TContext): Promise<string | undefined>;
|
|
23
|
+
protected retrieveRefreshToken(context: TContext): Promise<string | undefined>;
|
|
24
|
+
logout(context: TContext): Promise<void>;
|
|
10
25
|
}
|
|
@@ -5,77 +5,138 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.JwtStrategy = void 0;
|
|
7
7
|
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
8
|
-
const
|
|
8
|
+
const token_auth_strategy_1 = require("../token-auth.strategy");
|
|
9
9
|
const errors_1 = require("../../errors");
|
|
10
10
|
const jwt_tools_1 = require("./jwt.tools");
|
|
11
|
-
class JwtStrategy extends
|
|
11
|
+
class JwtStrategy extends token_auth_strategy_1.TokenAuthStrategy {
|
|
12
12
|
config;
|
|
13
13
|
session;
|
|
14
14
|
logger;
|
|
15
|
+
accessTokenConfig;
|
|
16
|
+
refreshTokenConfig;
|
|
15
17
|
constructor(config, session, logger) {
|
|
16
|
-
if (!config.accessToken.secretKey) {
|
|
18
|
+
if (!config.accessToken.issuer.secretKey) {
|
|
17
19
|
throw new errors_1.UndefinedTokenSecretError("Access");
|
|
18
20
|
}
|
|
19
|
-
if (config.refreshToken && !config.refreshToken.secretKey) {
|
|
21
|
+
if (config.refreshToken && !config.refreshToken.issuer.secretKey) {
|
|
20
22
|
throw new errors_1.UndefinedTokenSecretError("Refresh");
|
|
21
23
|
}
|
|
22
|
-
|
|
23
|
-
const refreshTokenConfig = (0, jwt_tools_1.prepareRefreshTokenConfig)(config);
|
|
24
|
-
super(config, {
|
|
25
|
-
...accessTokenConfig,
|
|
26
|
-
generate(payload) {
|
|
27
|
-
return jsonwebtoken_1.default.sign(payload, accessTokenConfig.secretKey, accessTokenConfig.signOptions);
|
|
28
|
-
},
|
|
29
|
-
verify(token) {
|
|
30
|
-
try {
|
|
31
|
-
if (!token)
|
|
32
|
-
throw new errors_1.UndefinedTokenError("Access");
|
|
33
|
-
if (!accessTokenConfig.secretKey)
|
|
34
|
-
throw new errors_1.UndefinedTokenSecretError("Access");
|
|
35
|
-
return new Promise((resolve, reject) => {
|
|
36
|
-
jsonwebtoken_1.default.verify(token, accessTokenConfig.secretKey, accessTokenConfig.verifyOptions, (err, payload) => {
|
|
37
|
-
if (err)
|
|
38
|
-
reject(err);
|
|
39
|
-
else
|
|
40
|
-
resolve(payload);
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
this.logger?.error("JWT verification failed:", error);
|
|
46
|
-
throw new errors_1.InvalidTokenError("Access");
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
}, {
|
|
50
|
-
...refreshTokenConfig,
|
|
51
|
-
generate(payload) {
|
|
52
|
-
return jsonwebtoken_1.default.sign(payload, refreshTokenConfig.secretKey, refreshTokenConfig.signOptions);
|
|
53
|
-
},
|
|
54
|
-
verify(token) {
|
|
55
|
-
try {
|
|
56
|
-
if (!token)
|
|
57
|
-
throw new errors_1.UndefinedTokenError("Refresh");
|
|
58
|
-
if (!refreshTokenConfig.secretKey)
|
|
59
|
-
throw new errors_1.UndefinedTokenSecretError("Refresh");
|
|
60
|
-
return new Promise((resolve, reject) => {
|
|
61
|
-
jsonwebtoken_1.default.verify(token, refreshTokenConfig.secretKey, refreshTokenConfig.verifyOptions, (err, payload) => {
|
|
62
|
-
if (err)
|
|
63
|
-
reject(err);
|
|
64
|
-
else
|
|
65
|
-
resolve(payload);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
this.logger?.error("JWT verification failed:", error);
|
|
71
|
-
throw new errors_1.InvalidTokenError("Refresh");
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
});
|
|
24
|
+
super(config, session, logger);
|
|
75
25
|
this.config = config;
|
|
76
26
|
this.session = session;
|
|
77
27
|
this.logger = logger;
|
|
28
|
+
this.accessTokenConfig = (0, jwt_tools_1.prepareAccessTokenConfig)(config.accessToken);
|
|
29
|
+
this.refreshTokenConfig = (0, jwt_tools_1.prepareRefreshTokenConfig)(config.refreshToken);
|
|
78
30
|
this.logger?.info("JWTStrategy initialized with provided configurations.");
|
|
79
31
|
}
|
|
32
|
+
async invalidateRefreshToken(token) {
|
|
33
|
+
await this.refreshTokenConfig.persistence.remove?.(token);
|
|
34
|
+
}
|
|
35
|
+
verifyAccessToken(token) {
|
|
36
|
+
try {
|
|
37
|
+
if (!token)
|
|
38
|
+
throw new errors_1.UndefinedTokenError("Access");
|
|
39
|
+
if (!this.accessTokenConfig.issuer.secretKey)
|
|
40
|
+
throw new errors_1.UndefinedTokenSecretError("Access");
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
jsonwebtoken_1.default.verify(token, this.accessTokenConfig.issuer.secretKey, this.accessTokenConfig.verifier.options, (err, payload) => {
|
|
43
|
+
if (err)
|
|
44
|
+
reject(err);
|
|
45
|
+
else
|
|
46
|
+
resolve(payload);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
this.logger?.error("JWT verification failed:", error);
|
|
52
|
+
throw new errors_1.InvalidTokenError("Access");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
verifyRefreshToken(token) {
|
|
56
|
+
try {
|
|
57
|
+
if (!token)
|
|
58
|
+
throw new errors_1.UndefinedTokenError("Refresh");
|
|
59
|
+
if (!this.refreshTokenConfig.issuer.secretKey)
|
|
60
|
+
throw new errors_1.UndefinedTokenSecretError("Refresh");
|
|
61
|
+
return new Promise((resolve, reject) => {
|
|
62
|
+
jsonwebtoken_1.default.verify(token, this.refreshTokenConfig.issuer.secretKey, this.refreshTokenConfig.verifier.options, (err, payload) => {
|
|
63
|
+
if (err)
|
|
64
|
+
reject(err);
|
|
65
|
+
else
|
|
66
|
+
resolve(payload);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
this.logger?.error("JWT verification failed:", error);
|
|
72
|
+
throw new errors_1.InvalidTokenError("Refresh");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
generateAccessToken(payload) {
|
|
76
|
+
const options = this.accessTokenConfig.issuer.options || {};
|
|
77
|
+
return jsonwebtoken_1.default.sign(payload, this.accessTokenConfig.issuer.secretKey, {
|
|
78
|
+
...options,
|
|
79
|
+
jti: payload.jti || crypto.randomUUID(),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
generateRefreshToken(payload) {
|
|
83
|
+
const options = this.refreshTokenConfig.issuer.options || {};
|
|
84
|
+
return jsonwebtoken_1.default.sign(payload, this.refreshTokenConfig.issuer.secretKey, {
|
|
85
|
+
...options,
|
|
86
|
+
jti: payload.jti || crypto.randomUUID(),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async storeAccessToken(token, context) {
|
|
90
|
+
if (this.accessTokenConfig.persistence.store) {
|
|
91
|
+
await this.accessTokenConfig.persistence.store(token, null, this.accessTokenConfig.issuer.options.expiresIn);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async storeRefreshToken(token, context) {
|
|
95
|
+
if (this.refreshTokenConfig.persistence.store) {
|
|
96
|
+
await this.refreshTokenConfig.persistence.store(token, null, this.refreshTokenConfig.issuer.options.expiresIn);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
embedAccessToken(token, context) {
|
|
100
|
+
if (this.accessTokenConfig.embed) {
|
|
101
|
+
this.accessTokenConfig.embed(context, token);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
(0, jwt_tools_1.setDefaultJwtHeader)(token, context);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
embedRefreshToken(token, context) {
|
|
108
|
+
if (this.refreshTokenConfig.embed) {
|
|
109
|
+
this.refreshTokenConfig.embed(context, token);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
(0, jwt_tools_1.setDefaultJwtCookie)(token, context);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
retrieveAccessToken(context) {
|
|
116
|
+
if (this.accessTokenConfig.retrieve) {
|
|
117
|
+
return this.accessTokenConfig.retrieve(context);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
return (context.req.headers.authorization?.split(" ")[1] ||
|
|
121
|
+
context.request.headers.authorization?.split(" ")[1] ||
|
|
122
|
+
context.headers.authorization?.split(" ")[1]);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
retrieveRefreshToken(context) {
|
|
126
|
+
if (this.refreshTokenConfig.retrieve) {
|
|
127
|
+
return this.refreshTokenConfig.retrieve(context);
|
|
128
|
+
}
|
|
129
|
+
return (context.req.cookies?.refreshToken ||
|
|
130
|
+
context.request.cookies?.refreshToken ||
|
|
131
|
+
context.cookies.refreshToken);
|
|
132
|
+
}
|
|
133
|
+
async logout(context) {
|
|
134
|
+
const refreshToken = await this.retrieveRefreshToken(context);
|
|
135
|
+
if (refreshToken) {
|
|
136
|
+
await this.invalidateRefreshToken(refreshToken);
|
|
137
|
+
(0, jwt_tools_1.clearDefaultJwtCookie)(context);
|
|
138
|
+
(0, jwt_tools_1.clearDefaultJwtHeader)(context);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
80
141
|
}
|
|
81
142
|
exports.JwtStrategy = JwtStrategy;
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const prepareAccessTokenConfig: (config:
|
|
3
|
-
export declare const prepareRefreshTokenConfig: (config:
|
|
1
|
+
import { TokenConfig } from "../../types";
|
|
2
|
+
export declare const prepareAccessTokenConfig: <TContext = any>(config: TokenConfig<TContext>) => TokenConfig<TContext>;
|
|
3
|
+
export declare const prepareRefreshTokenConfig: <TContext = any>(config: TokenConfig<TContext>) => TokenConfig<TContext>;
|
|
4
|
+
export declare const setDefaultJwtCookie: (token: string, context: any) => void;
|
|
5
|
+
export declare const setDefaultJwtHeader: (token: string, context: any) => void;
|
|
6
|
+
export declare const clearDefaultJwtHeader: (context: any) => void;
|
|
7
|
+
export declare const clearDefaultJwtCookie: (context: any) => void;
|