@lyxa.ai/core 1.0.9 → 1.0.11
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/libraries/auth/index.d.ts +65 -2
- package/dist/libraries/auth/index.js +208 -7
- package/dist/libraries/auth/index.js.map +1 -1
- package/dist/libraries/auth/refreshtoken.d.ts +15 -0
- package/dist/libraries/auth/refreshtoken.js +96 -0
- package/dist/libraries/auth/refreshtoken.js.map +1 -0
- package/dist/libraries/auth/repository.d.ts +18 -0
- package/dist/libraries/auth/repository.js +47 -0
- package/dist/libraries/auth/repository.js.map +1 -0
- package/dist/libraries/index.d.ts +2 -0
- package/dist/libraries/index.js +4 -0
- package/dist/libraries/index.js.map +1 -1
- package/dist/libraries/mongo/models/address.model.d.ts +19 -0
- package/dist/libraries/mongo/models/address.model.js +91 -0
- package/dist/libraries/mongo/models/address.model.js.map +1 -0
- package/dist/libraries/mongo/models/duration.model.d.ts +4 -0
- package/dist/libraries/mongo/models/duration.model.js +27 -0
- package/dist/libraries/mongo/models/duration.model.js.map +1 -0
- package/dist/libraries/mongo/models/work-hour.model.d.ts +4 -5
- package/dist/libraries/mongo/models/work-hour.model.js +9 -5
- package/dist/libraries/mongo/models/work-hour.model.js.map +1 -1
- package/dist/libraries/trpc/context.d.ts +4 -0
- package/dist/libraries/trpc/context.js +4 -1
- package/dist/libraries/trpc/context.js.map +1 -1
- package/dist/libraries/trpc/middlewares/auth.d.ts +11 -2
- package/dist/libraries/trpc/middlewares/auth.js +54 -9
- package/dist/libraries/trpc/middlewares/auth.js.map +1 -1
- package/dist/utilities/enum.d.ts +8 -0
- package/dist/utilities/enum.js +11 -1
- package/dist/utilities/enum.js.map +1 -1
- package/dist/utilities/validation/common-validation.d.ts +233 -36
- package/dist/utilities/validation/common-validation.js +44 -16
- package/dist/utilities/validation/common-validation.js.map +1 -1
- package/dist/utilities/validation/global-validation.d.ts +3 -4
- package/dist/utilities/validation/global-validation.js +48 -42
- package/dist/utilities/validation/global-validation.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,14 +1,77 @@
|
|
|
1
1
|
import { SignOptions } from "jsonwebtoken";
|
|
2
2
|
import { EntityContext } from "../trpc/context";
|
|
3
|
+
import { RefreshToken } from "./refreshtoken";
|
|
3
4
|
export declare enum AuthEntityType {
|
|
4
5
|
USER = "USER",
|
|
5
6
|
SELLER = "SELLER",
|
|
6
7
|
DELIVERY_BOY = "DELIVERY_BOY",
|
|
7
8
|
CRM = "CRM"
|
|
8
9
|
}
|
|
9
|
-
export declare
|
|
10
|
+
export declare enum TokenType {
|
|
11
|
+
ACCESS = "ACCESS",
|
|
12
|
+
REFRESH = "REFRESH"
|
|
13
|
+
}
|
|
14
|
+
export interface RefreshTokenRecord {
|
|
15
|
+
token: string;
|
|
16
|
+
entityId: string;
|
|
17
|
+
entityType: AuthEntityType;
|
|
18
|
+
expiresAt: Date;
|
|
19
|
+
isRevoked: boolean;
|
|
20
|
+
metadata?: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
export declare function signAccessToken(entity: {
|
|
10
23
|
id: string;
|
|
11
24
|
type: AuthEntityType;
|
|
12
25
|
parameters: Record<string, unknown>;
|
|
13
26
|
}, options?: SignOptions): Promise<string>;
|
|
14
|
-
export declare function
|
|
27
|
+
export declare function generateRefreshToken(entity: {
|
|
28
|
+
id: string;
|
|
29
|
+
type: AuthEntityType;
|
|
30
|
+
parameters?: Record<string, unknown>;
|
|
31
|
+
}, options?: {
|
|
32
|
+
expiresIn?: string | number;
|
|
33
|
+
}): Promise<string>;
|
|
34
|
+
export declare function verifyAccessToken(entityTypes: AuthEntityType[], token: string): Promise<EntityContext | undefined>;
|
|
35
|
+
export declare function validateRefreshToken(token: string): Promise<{
|
|
36
|
+
valid: boolean;
|
|
37
|
+
entity?: {
|
|
38
|
+
id: string;
|
|
39
|
+
type: AuthEntityType;
|
|
40
|
+
parameters?: Record<string, unknown>;
|
|
41
|
+
};
|
|
42
|
+
}>;
|
|
43
|
+
export declare function refreshTokens(refreshToken: string): Promise<{
|
|
44
|
+
accessToken: string;
|
|
45
|
+
refreshToken: string;
|
|
46
|
+
entity: {
|
|
47
|
+
id: string;
|
|
48
|
+
type: AuthEntityType;
|
|
49
|
+
};
|
|
50
|
+
} | null>;
|
|
51
|
+
export declare function revokeRefreshToken(token: string): Promise<boolean>;
|
|
52
|
+
export declare function revokeAllRefreshTokens(entityId: string, entityType: AuthEntityType): Promise<boolean>;
|
|
53
|
+
export declare function signTokenPair(entity: {
|
|
54
|
+
id: string;
|
|
55
|
+
type: AuthEntityType;
|
|
56
|
+
parameters?: Record<string, unknown>;
|
|
57
|
+
}, options?: {
|
|
58
|
+
accessTokenOptions?: SignOptions;
|
|
59
|
+
refreshTokenExpiresIn?: string | number;
|
|
60
|
+
}): Promise<{
|
|
61
|
+
accessToken: string;
|
|
62
|
+
refreshToken: string;
|
|
63
|
+
}>;
|
|
64
|
+
export declare function handleTokenRenewal(refreshToken: string): Promise<{
|
|
65
|
+
success: boolean;
|
|
66
|
+
entity?: {
|
|
67
|
+
id: string;
|
|
68
|
+
type: AuthEntityType;
|
|
69
|
+
parameters: Record<string, unknown>;
|
|
70
|
+
};
|
|
71
|
+
tokenStatus: 'valid' | 'expired' | 'revoked' | 'invalid';
|
|
72
|
+
newTokens?: {
|
|
73
|
+
accessToken: string;
|
|
74
|
+
refreshToken?: string | null;
|
|
75
|
+
};
|
|
76
|
+
}>;
|
|
77
|
+
export declare const RefreshTokenModel: import("@typegoose/typegoose").ReturnModelType<typeof RefreshToken>;
|
|
@@ -3,11 +3,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.AuthEntityType = void 0;
|
|
7
|
-
exports.
|
|
8
|
-
exports.
|
|
6
|
+
exports.RefreshTokenModel = exports.TokenType = exports.AuthEntityType = void 0;
|
|
7
|
+
exports.signAccessToken = signAccessToken;
|
|
8
|
+
exports.generateRefreshToken = generateRefreshToken;
|
|
9
|
+
exports.verifyAccessToken = verifyAccessToken;
|
|
10
|
+
exports.validateRefreshToken = validateRefreshToken;
|
|
11
|
+
exports.refreshTokens = refreshTokens;
|
|
12
|
+
exports.revokeRefreshToken = revokeRefreshToken;
|
|
13
|
+
exports.revokeAllRefreshTokens = revokeAllRefreshTokens;
|
|
14
|
+
exports.signTokenPair = signTokenPair;
|
|
15
|
+
exports.handleTokenRenewal = handleTokenRenewal;
|
|
9
16
|
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
10
17
|
const index_1 = require("../../index");
|
|
18
|
+
const crypto_1 = require("crypto");
|
|
19
|
+
const refreshtoken_1 = require("./refreshtoken");
|
|
11
20
|
var AuthEntityType;
|
|
12
21
|
(function (AuthEntityType) {
|
|
13
22
|
AuthEntityType["USER"] = "USER";
|
|
@@ -15,7 +24,12 @@ var AuthEntityType;
|
|
|
15
24
|
AuthEntityType["DELIVERY_BOY"] = "DELIVERY_BOY";
|
|
16
25
|
AuthEntityType["CRM"] = "CRM";
|
|
17
26
|
})(AuthEntityType || (exports.AuthEntityType = AuthEntityType = {}));
|
|
18
|
-
|
|
27
|
+
var TokenType;
|
|
28
|
+
(function (TokenType) {
|
|
29
|
+
TokenType["ACCESS"] = "ACCESS";
|
|
30
|
+
TokenType["REFRESH"] = "REFRESH";
|
|
31
|
+
})(TokenType || (exports.TokenType = TokenType = {}));
|
|
32
|
+
async function signAccessToken(entity, options) {
|
|
19
33
|
if (!entity?.type) {
|
|
20
34
|
throw new Error('Entity type is required to sign token');
|
|
21
35
|
}
|
|
@@ -29,17 +43,204 @@ async function signToken(entity, options) {
|
|
|
29
43
|
id: entity.id,
|
|
30
44
|
type: entity.type,
|
|
31
45
|
parameters: entity.parameters,
|
|
46
|
+
tokenType: TokenType.ACCESS
|
|
32
47
|
};
|
|
33
|
-
|
|
48
|
+
const tokenOptions = {
|
|
49
|
+
...options,
|
|
50
|
+
expiresIn: options?.expiresIn || '1d'
|
|
51
|
+
};
|
|
52
|
+
return jsonwebtoken_1.default.sign(payload, secret, tokenOptions);
|
|
34
53
|
}
|
|
35
|
-
async function
|
|
54
|
+
async function generateRefreshToken(entity, options) {
|
|
55
|
+
const tokenValue = (0, crypto_1.randomBytes)(40).toString('hex');
|
|
56
|
+
const expiresIn = options?.expiresIn || '7d';
|
|
57
|
+
const expiresAt = new Date();
|
|
58
|
+
if (typeof expiresIn === 'string') {
|
|
59
|
+
const match = expiresIn.match(/^(\d+)([smhdwy])$/);
|
|
60
|
+
if (match) {
|
|
61
|
+
const value = parseInt(match[1]);
|
|
62
|
+
const unit = match[2];
|
|
63
|
+
switch (unit) {
|
|
64
|
+
case 's':
|
|
65
|
+
expiresAt.setSeconds(expiresAt.getSeconds() + value);
|
|
66
|
+
break;
|
|
67
|
+
case 'm':
|
|
68
|
+
expiresAt.setMinutes(expiresAt.getMinutes() + value);
|
|
69
|
+
break;
|
|
70
|
+
case 'h':
|
|
71
|
+
expiresAt.setHours(expiresAt.getHours() + value);
|
|
72
|
+
break;
|
|
73
|
+
case 'd':
|
|
74
|
+
expiresAt.setDate(expiresAt.getDate() + value);
|
|
75
|
+
break;
|
|
76
|
+
case 'w':
|
|
77
|
+
expiresAt.setDate(expiresAt.getDate() + (value * 7));
|
|
78
|
+
break;
|
|
79
|
+
case 'y':
|
|
80
|
+
expiresAt.setFullYear(expiresAt.getFullYear() + value);
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
expiresAt.setDate(expiresAt.getDate() + 7);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else if (typeof expiresIn === 'number') {
|
|
89
|
+
expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn);
|
|
90
|
+
}
|
|
91
|
+
await storeRefreshToken({
|
|
92
|
+
token: tokenValue,
|
|
93
|
+
entityId: entity.id,
|
|
94
|
+
entityType: entity.type,
|
|
95
|
+
expiresAt,
|
|
96
|
+
isRevoked: false,
|
|
97
|
+
metadata: entity.parameters
|
|
98
|
+
});
|
|
99
|
+
return tokenValue;
|
|
100
|
+
}
|
|
101
|
+
async function storeRefreshToken(tokenRecord) {
|
|
102
|
+
const tokenRepository = (0, index_1.getLibraries)().getAuthTokenRepository();
|
|
103
|
+
await tokenRepository.saveRefreshToken(tokenRecord);
|
|
104
|
+
}
|
|
105
|
+
async function verifyAccessToken(entityTypes, token) {
|
|
36
106
|
for (const entityType of entityTypes) {
|
|
37
107
|
const secret = await (0, index_1.getLibraries)().getSecretsService().getKey(entityType.toUpperCase() + "_JWT_TOKEN");
|
|
38
108
|
try {
|
|
39
|
-
|
|
109
|
+
const decoded = jsonwebtoken_1.default.verify(token, secret);
|
|
110
|
+
if (decoded.tokenType !== TokenType.ACCESS) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
return decoded;
|
|
40
114
|
}
|
|
41
115
|
catch (err) {
|
|
42
116
|
}
|
|
43
117
|
}
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
async function validateRefreshToken(token) {
|
|
121
|
+
const tokenRepository = (0, index_1.getLibraries)().getAuthTokenRepository();
|
|
122
|
+
const storedToken = await tokenRepository.findRefreshToken(token);
|
|
123
|
+
if (!storedToken) {
|
|
124
|
+
return { valid: false };
|
|
125
|
+
}
|
|
126
|
+
if (storedToken.expiresAt && new Date() > storedToken.expiresAt) {
|
|
127
|
+
return { valid: false };
|
|
128
|
+
}
|
|
129
|
+
if (storedToken.isRevoked) {
|
|
130
|
+
return { valid: false };
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
valid: true,
|
|
134
|
+
entity: {
|
|
135
|
+
id: storedToken.entityId,
|
|
136
|
+
type: storedToken.entityType,
|
|
137
|
+
parameters: storedToken.metadata
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
async function refreshTokens(refreshToken) {
|
|
142
|
+
const validation = await validateRefreshToken(refreshToken);
|
|
143
|
+
if (!validation.valid || !validation.entity) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
await revokeRefreshToken(refreshToken);
|
|
147
|
+
const entity = validation.entity;
|
|
148
|
+
const newAccessToken = await signAccessToken({
|
|
149
|
+
id: entity.id,
|
|
150
|
+
type: entity.type,
|
|
151
|
+
parameters: entity.parameters || {}
|
|
152
|
+
});
|
|
153
|
+
const newRefreshToken = await generateRefreshToken({
|
|
154
|
+
id: entity.id,
|
|
155
|
+
type: entity.type,
|
|
156
|
+
parameters: entity.parameters
|
|
157
|
+
});
|
|
158
|
+
return {
|
|
159
|
+
accessToken: newAccessToken,
|
|
160
|
+
refreshToken: newRefreshToken,
|
|
161
|
+
entity: {
|
|
162
|
+
id: entity.id,
|
|
163
|
+
type: entity.type
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
async function revokeRefreshToken(token) {
|
|
168
|
+
const tokenRepository = (0, index_1.getLibraries)().getAuthTokenRepository();
|
|
169
|
+
return tokenRepository.revokeRefreshToken(token);
|
|
170
|
+
}
|
|
171
|
+
async function revokeAllRefreshTokens(entityId, entityType) {
|
|
172
|
+
const tokenRepository = (0, index_1.getLibraries)().getAuthTokenRepository();
|
|
173
|
+
return tokenRepository.revokeAllRefreshTokensForEntity(entityId, entityType);
|
|
174
|
+
}
|
|
175
|
+
async function signTokenPair(entity, options) {
|
|
176
|
+
const accessToken = await signAccessToken({
|
|
177
|
+
id: entity.id,
|
|
178
|
+
type: entity.type,
|
|
179
|
+
parameters: entity.parameters || {}
|
|
180
|
+
}, options?.accessTokenOptions);
|
|
181
|
+
const refreshToken = await generateRefreshToken({
|
|
182
|
+
id: entity.id,
|
|
183
|
+
type: entity.type,
|
|
184
|
+
parameters: entity.parameters
|
|
185
|
+
}, { expiresIn: options?.refreshTokenExpiresIn });
|
|
186
|
+
return {
|
|
187
|
+
accessToken,
|
|
188
|
+
refreshToken
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
async function handleTokenRenewal(refreshToken) {
|
|
192
|
+
const tokenRepository = (0, index_1.getLibraries)().getAuthTokenRepository();
|
|
193
|
+
const storedToken = await tokenRepository.findRefreshToken(refreshToken);
|
|
194
|
+
if (!storedToken) {
|
|
195
|
+
return {
|
|
196
|
+
success: false,
|
|
197
|
+
tokenStatus: 'invalid'
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
const isRevoked = storedToken.isRevoked;
|
|
201
|
+
if (isRevoked) {
|
|
202
|
+
return {
|
|
203
|
+
success: false,
|
|
204
|
+
tokenStatus: 'revoked'
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
const isExpired = storedToken.isExpired();
|
|
208
|
+
const entityData = {
|
|
209
|
+
id: storedToken.entityId,
|
|
210
|
+
type: storedToken.entityType,
|
|
211
|
+
parameters: storedToken.metadata || {}
|
|
212
|
+
};
|
|
213
|
+
if (isExpired) {
|
|
214
|
+
const newTokens = await signTokenPair({
|
|
215
|
+
id: storedToken.entityId,
|
|
216
|
+
type: storedToken.entityType,
|
|
217
|
+
parameters: storedToken.metadata || {}
|
|
218
|
+
});
|
|
219
|
+
await tokenRepository.revokeRefreshToken(refreshToken);
|
|
220
|
+
return {
|
|
221
|
+
success: true,
|
|
222
|
+
entity: entityData,
|
|
223
|
+
tokenStatus: 'expired',
|
|
224
|
+
newTokens: {
|
|
225
|
+
accessToken: newTokens.accessToken,
|
|
226
|
+
refreshToken: newTokens.refreshToken
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
const newAccessToken = await signAccessToken({
|
|
231
|
+
id: storedToken.entityId,
|
|
232
|
+
type: storedToken.entityType,
|
|
233
|
+
parameters: storedToken.metadata || {}
|
|
234
|
+
});
|
|
235
|
+
return {
|
|
236
|
+
success: true,
|
|
237
|
+
entity: entityData,
|
|
238
|
+
tokenStatus: 'valid',
|
|
239
|
+
newTokens: {
|
|
240
|
+
accessToken: newAccessToken,
|
|
241
|
+
refreshToken: null
|
|
242
|
+
}
|
|
243
|
+
};
|
|
44
244
|
}
|
|
245
|
+
exports.RefreshTokenModel = (0, index_1.createGlobalModel)(refreshtoken_1.RefreshToken);
|
|
45
246
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"/","sources":["libraries/auth/index.ts"],"names":[],"mappings":";;;;;;AAeA,8BAuBC;AAED,kCASC;AAjDD,gEAA8C;AAC9C,uCAAyC;AAGzC,IAAY,cAKX;AALD,WAAY,cAAc;IACtB,+BAAa,CAAA;IACb,mCAAiB,CAAA;IACjB,+CAA6B,CAAA;IAC7B,6BAAW,CAAA;AACf,CAAC,EALW,cAAc,8BAAd,cAAc,QAKzB;AAMM,KAAK,UAAU,SAAS,CAC3B,MAAiF,EACjF,OAAqB;IAErB,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,IAAA,oBAAY,GAAE;SAC9B,iBAAiB,EAAE;SACnB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAEtD,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,mCAAmC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,OAAO,GAAG;QACZ,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,UAAU,EAAE,MAAM,CAAC,UAAU;KAChC,CAAC;IAEF,OAAO,sBAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAEM,KAAK,UAAU,WAAW,CAAC,WAA6B,EAAE,KAAa;IAC1E,KAAI,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,IAAA,oBAAY,GAAE,CAAC,iBAAiB,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE,GAAG,YAAY,CAAC,CAAC;QAExG,IAAI,CAAC;YACD,OAAO,sBAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAO,CAAkB,CAAC;QACvD,CAAC;QAAC,OAAM,GAAG,EAAE,CAAC;QACd,CAAC;IACL,CAAC;AACL,CAAC","sourcesContent":["import jwt, {SignOptions} from \"jsonwebtoken\";\r\nimport {getLibraries} from \"../../index\";\r\nimport {EntityContext} from \"../trpc/context\";\r\n\r\nexport enum AuthEntityType {\r\n USER = \"USER\",\r\n SELLER = \"SELLER\",\r\n DELIVERY_BOY = \"DELIVERY_BOY\",\r\n CRM = \"CRM\"\r\n}\r\n\r\n/**\r\n * Sign a JWT for the given entity (id + type).\r\n * It will fetch the secret for that entity type and create a token.\r\n */\r\nexport async function signToken(\r\n entity: { id: string; type: AuthEntityType, parameters: Record<string, unknown> },\r\n options?: SignOptions\r\n): Promise<string> {\r\n if (!entity?.type) {\r\n throw new Error('Entity type is required to sign token');\r\n }\r\n\r\n const secret = await getLibraries()\r\n .getSecretsService()\r\n .getKey(`${entity.type.toUpperCase()}_JWT_TOKEN`);\r\n\r\n if (!secret) {\r\n throw new Error(`No secret found for entity type ${entity.type}`);\r\n }\r\n\r\n const payload = {\r\n id: entity.id,\r\n type: entity.type,\r\n parameters: entity.parameters,\r\n };\r\n\r\n return jwt.sign(payload, secret, options);\r\n}\r\n\r\nexport async function verifyToken(entityTypes: AuthEntityType[], token: string): Promise<EntityContext | undefined> {\r\n for(const entityType of entityTypes) {\r\n const secret = await getLibraries().getSecretsService().getKey(entityType.toUpperCase() + \"_JWT_TOKEN\");\r\n\r\n try {\r\n return jwt.verify(token, secret!) as EntityContext;\r\n } catch(err) {\r\n }\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"/","sources":["libraries/auth/index.ts"],"names":[],"mappings":"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","sourcesContent":["import jwt, { SignOptions, JwtPayload } from \"jsonwebtoken\";\r\nimport {createGlobalModel, getLibraries} from \"../../index\";\r\nimport { EntityContext } from \"../trpc/context\";\r\nimport { randomBytes } from \"crypto\";\r\nimport {getModelForClass} from \"@typegoose/typegoose\";\r\nimport {RefreshToken} from \"./refreshtoken\";\r\n\r\nexport enum AuthEntityType {\r\n USER = \"USER\",\r\n SELLER = \"SELLER\",\r\n DELIVERY_BOY = \"DELIVERY_BOY\",\r\n CRM = \"CRM\"\r\n}\r\n\r\nexport enum TokenType {\r\n ACCESS = \"ACCESS\",\r\n REFRESH = \"REFRESH\"\r\n}\r\n\r\nexport interface RefreshTokenRecord {\r\n token: string;\r\n entityId: string;\r\n entityType: AuthEntityType;\r\n expiresAt: Date;\r\n isRevoked: boolean;\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Sign a JWT access token for the given entity (id + type).\r\n * It will fetch the secret for that entity type and create a token.\r\n */\r\nexport async function signAccessToken(\r\n entity: { id: string; type: AuthEntityType, parameters: Record<string, unknown> },\r\n options?: SignOptions\r\n): Promise<string> {\r\n if (!entity?.type) {\r\n throw new Error('Entity type is required to sign token');\r\n }\r\n\r\n const secret = await getLibraries()\r\n .getSecretsService()\r\n .getKey(`${entity.type.toUpperCase()}_JWT_TOKEN`);\r\n\r\n if (!secret) {\r\n throw new Error(`No secret found for entity type ${entity.type}`);\r\n }\r\n\r\n const payload = {\r\n id: entity.id,\r\n type: entity.type,\r\n parameters: entity.parameters,\r\n tokenType: TokenType.ACCESS\r\n };\r\n\r\n const tokenOptions: SignOptions = {\r\n ...options,\r\n expiresIn: options?.expiresIn || '1d'\r\n };\r\n\r\n return jwt.sign(payload, secret, tokenOptions);\r\n}\r\n\r\n/**\r\n * Generate a refresh token for the given entity\r\n */\r\nexport async function generateRefreshToken(\r\n entity: { id: string; type: AuthEntityType, parameters?: Record<string, unknown> },\r\n options?: { expiresIn?: string | number }\r\n): Promise<string> {\r\n const tokenValue = randomBytes(40).toString('hex');\r\n\r\n const expiresIn = options?.expiresIn || '7d';\r\n const expiresAt = new Date();\r\n\r\n if (typeof expiresIn === 'string') {\r\n // Parse duration strings like '7d', '30d', etc.\r\n const match = expiresIn.match(/^(\\d+)([smhdwy])$/);\r\n if (match) {\r\n const value = parseInt(match[1]);\r\n const unit = match[2];\r\n\r\n switch (unit) {\r\n case 's': expiresAt.setSeconds(expiresAt.getSeconds() + value); break;\r\n case 'm': expiresAt.setMinutes(expiresAt.getMinutes() + value); break;\r\n case 'h': expiresAt.setHours(expiresAt.getHours() + value); break;\r\n case 'd': expiresAt.setDate(expiresAt.getDate() + value); break;\r\n case 'w': expiresAt.setDate(expiresAt.getDate() + (value * 7)); break;\r\n case 'y': expiresAt.setFullYear(expiresAt.getFullYear() + value); break;\r\n }\r\n } else {\r\n // Default to 7 days if format is invalid\r\n expiresAt.setDate(expiresAt.getDate() + 7);\r\n }\r\n } else if (typeof expiresIn === 'number') {\r\n // Interpret number as seconds\r\n expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn);\r\n }\r\n\r\n await storeRefreshToken({\r\n token: tokenValue,\r\n entityId: entity.id,\r\n entityType: entity.type,\r\n expiresAt,\r\n isRevoked: false,\r\n metadata: entity.parameters\r\n });\r\n\r\n return tokenValue;\r\n}\r\n\r\n/**\r\n * Store a refresh token in the database\r\n */\r\nasync function storeRefreshToken(tokenRecord: RefreshTokenRecord): Promise<void> {\r\n const tokenRepository = getLibraries().getAuthTokenRepository();\r\n await tokenRepository.saveRefreshToken(tokenRecord);\r\n}\r\n\r\n/**\r\n * Verify an access token for the given entity types\r\n */\r\nexport async function verifyAccessToken(entityTypes: AuthEntityType[], token: string): Promise<EntityContext | undefined> {\r\n for(const entityType of entityTypes) {\r\n const secret = await getLibraries().getSecretsService().getKey(entityType.toUpperCase() + \"_JWT_TOKEN\");\r\n\r\n try {\r\n const decoded = jwt.verify(token, secret!) as EntityContext & { tokenType?: TokenType };\r\n\r\n // Verify this is an access token\r\n if (decoded.tokenType !== TokenType.ACCESS) {\r\n continue;\r\n }\r\n\r\n return decoded;\r\n } catch(err) {\r\n // Continue to the next entity type\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Validate a refresh token and return the associated entity\r\n */\r\nexport async function validateRefreshToken(token: string): Promise<{\r\n valid: boolean;\r\n entity?: { id: string; type: AuthEntityType; parameters?: Record<string, unknown> };\r\n}> {\r\n const tokenRepository = getLibraries().getAuthTokenRepository();\r\n const storedToken = await tokenRepository.findRefreshToken(token);\r\n\r\n if (!storedToken) {\r\n return { valid: false };\r\n }\r\n\r\n if (storedToken.expiresAt && new Date() > storedToken.expiresAt) {\r\n return { valid: false };\r\n }\r\n\r\n if (storedToken.isRevoked) {\r\n return { valid: false };\r\n }\r\n\r\n return {\r\n valid: true,\r\n entity: {\r\n id: storedToken.entityId,\r\n type: storedToken.entityType,\r\n parameters: storedToken.metadata\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Refresh authentication tokens\r\n * Returns new access and refresh tokens\r\n */\r\nexport async function refreshTokens(refreshToken: string): Promise<{\r\n accessToken: string;\r\n refreshToken: string;\r\n entity: { id: string; type: AuthEntityType };\r\n} | null> {\r\n // Validate the refresh token\r\n const validation = await validateRefreshToken(refreshToken);\r\n\r\n if (!validation.valid || !validation.entity) {\r\n return null;\r\n }\r\n\r\n await revokeRefreshToken(refreshToken);\r\n\r\n // Create new tokens\r\n const entity = validation.entity;\r\n const newAccessToken = await signAccessToken({\r\n id: entity.id,\r\n type: entity.type,\r\n parameters: entity.parameters || {}\r\n });\r\n\r\n const newRefreshToken = await generateRefreshToken({\r\n id: entity.id,\r\n type: entity.type,\r\n parameters: entity.parameters\r\n });\r\n\r\n return {\r\n accessToken: newAccessToken,\r\n refreshToken: newRefreshToken,\r\n entity: {\r\n id: entity.id,\r\n type: entity.type\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Revoke a refresh token\r\n */\r\nexport async function revokeRefreshToken(token: string): Promise<boolean> {\r\n const tokenRepository = getLibraries().getAuthTokenRepository();\r\n return tokenRepository.revokeRefreshToken(token);\r\n}\r\n\r\n/**\r\n * Revoke all refresh tokens for a specific entity\r\n */\r\nexport async function revokeAllRefreshTokens(entityId: string, entityType: AuthEntityType): Promise<boolean> {\r\n const tokenRepository = getLibraries().getAuthTokenRepository();\r\n return tokenRepository.revokeAllRefreshTokensForEntity(entityId, entityType);\r\n}\r\n\r\n/**\r\n * Sign both access and refresh tokens - utility for initial login/authentication\r\n */\r\nexport async function signTokenPair(\r\n entity: { id: string; type: AuthEntityType; parameters?: Record<string, unknown> },\r\n options?: { accessTokenOptions?: SignOptions; refreshTokenExpiresIn?: string | number }\r\n): Promise<{\r\n accessToken: string;\r\n refreshToken: string;\r\n}> {\r\n const accessToken = await signAccessToken({\r\n id: entity.id,\r\n type: entity.type,\r\n parameters: entity.parameters || {}\r\n }, options?.accessTokenOptions);\r\n\r\n const refreshToken = await generateRefreshToken({\r\n id: entity.id,\r\n type: entity.type,\r\n parameters: entity.parameters\r\n }, { expiresIn: options?.refreshTokenExpiresIn });\r\n\r\n return {\r\n accessToken,\r\n refreshToken\r\n };\r\n}\r\n\r\n/**\r\n * Handle the refresh token validation and renewal logic\r\n * @param refreshToken The refresh token to validate or renew\r\n * @returns Result object with token status and renewal information\r\n */\r\nexport async function handleTokenRenewal(\r\n refreshToken: string,\r\n): Promise<{\r\n success: boolean;\r\n entity?: {\r\n id: string;\r\n type: AuthEntityType;\r\n parameters: Record<string, unknown>;\r\n };\r\n tokenStatus: 'valid' | 'expired' | 'revoked' | 'invalid';\r\n newTokens?: {\r\n accessToken: string;\r\n refreshToken?: string | null;\r\n };\r\n}> {\r\n const tokenRepository = getLibraries().getAuthTokenRepository();\r\n\r\n const storedToken = await tokenRepository.findRefreshToken(refreshToken);\r\n\r\n if (!storedToken) {\r\n return {\r\n success: false,\r\n tokenStatus: 'invalid'\r\n };\r\n }\r\n\r\n const isRevoked = storedToken.isRevoked;\r\n if (isRevoked) {\r\n return {\r\n success: false,\r\n tokenStatus: 'revoked'\r\n };\r\n }\r\n\r\n const isExpired = storedToken.isExpired();\r\n\r\n const entityData = {\r\n id: storedToken.entityId,\r\n type: storedToken.entityType,\r\n parameters: storedToken.metadata || {}\r\n };\r\n\r\n if (isExpired) {\r\n const newTokens = await signTokenPair({\r\n id: storedToken.entityId,\r\n type: storedToken.entityType,\r\n parameters: storedToken.metadata || {}\r\n });\r\n\r\n await tokenRepository.revokeRefreshToken(refreshToken);\r\n\r\n return {\r\n success: true,\r\n entity: entityData,\r\n tokenStatus: 'expired',\r\n newTokens: {\r\n accessToken: newTokens.accessToken,\r\n refreshToken: newTokens.refreshToken\r\n }\r\n };\r\n }\r\n\r\n const newAccessToken = await signAccessToken({\r\n id: storedToken.entityId,\r\n type: storedToken.entityType,\r\n parameters: storedToken.metadata || {}\r\n });\r\n\r\n return {\r\n success: true,\r\n entity: entityData,\r\n tokenStatus: 'valid',\r\n newTokens: {\r\n accessToken: newAccessToken,\r\n refreshToken: null\r\n }\r\n };\r\n}\r\n\r\nexport const RefreshTokenModel = createGlobalModel(RefreshToken);\r\n\r\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { DocumentType, ReturnModelType } from '@typegoose/typegoose';
|
|
2
|
+
import { TimeStamps } from '@typegoose/typegoose/lib/defaultClasses';
|
|
3
|
+
import { AuthEntityType } from "./index";
|
|
4
|
+
export declare class RefreshToken extends TimeStamps {
|
|
5
|
+
token: string;
|
|
6
|
+
entityId: string;
|
|
7
|
+
entityType: AuthEntityType;
|
|
8
|
+
expiresAt?: Date | null;
|
|
9
|
+
isRevoked: boolean;
|
|
10
|
+
metadata?: Record<string, unknown>;
|
|
11
|
+
static findValidToken(this: ReturnModelType<typeof RefreshToken>, token: string): Promise<DocumentType<RefreshToken> | null>;
|
|
12
|
+
static revokeAllForEntity(this: ReturnModelType<typeof RefreshToken>, entityId: string, entityType: AuthEntityType): Promise<number>;
|
|
13
|
+
isExpired(): boolean;
|
|
14
|
+
static cleanupExpiredTokens(this: ReturnModelType<typeof RefreshToken>, olderThan?: Date): Promise<number>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var RefreshToken_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.RefreshToken = void 0;
|
|
14
|
+
const typegoose_1 = require("@typegoose/typegoose");
|
|
15
|
+
const defaultClasses_1 = require("@typegoose/typegoose/lib/defaultClasses");
|
|
16
|
+
const index_1 = require("./index");
|
|
17
|
+
let RefreshToken = RefreshToken_1 = class RefreshToken extends defaultClasses_1.TimeStamps {
|
|
18
|
+
token;
|
|
19
|
+
entityId;
|
|
20
|
+
entityType;
|
|
21
|
+
expiresAt;
|
|
22
|
+
isRevoked;
|
|
23
|
+
metadata;
|
|
24
|
+
static async findValidToken(token) {
|
|
25
|
+
const query = { token, isRevoked: false };
|
|
26
|
+
query.$or = [
|
|
27
|
+
{ expiresAt: { $exists: false } },
|
|
28
|
+
{ expiresAt: null },
|
|
29
|
+
{ expiresAt: { $gt: new Date() } }
|
|
30
|
+
];
|
|
31
|
+
return this.findOne(query);
|
|
32
|
+
}
|
|
33
|
+
static async revokeAllForEntity(entityId, entityType) {
|
|
34
|
+
const result = await this.updateMany({ entityId, entityType, isRevoked: false }, { isRevoked: true });
|
|
35
|
+
return result.modifiedCount;
|
|
36
|
+
}
|
|
37
|
+
isExpired() {
|
|
38
|
+
if (!this.expiresAt)
|
|
39
|
+
return false;
|
|
40
|
+
return new Date() > this.expiresAt;
|
|
41
|
+
}
|
|
42
|
+
static async cleanupExpiredTokens(olderThan) {
|
|
43
|
+
const cutoffDate = olderThan || new Date();
|
|
44
|
+
const result = await this.deleteMany({
|
|
45
|
+
expiresAt: { $ne: null, $lt: cutoffDate },
|
|
46
|
+
isRevoked: true
|
|
47
|
+
});
|
|
48
|
+
return result.deletedCount;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
exports.RefreshToken = RefreshToken;
|
|
52
|
+
__decorate([
|
|
53
|
+
(0, typegoose_1.prop)({ required: true, type: () => String, unique: true }),
|
|
54
|
+
__metadata("design:type", String)
|
|
55
|
+
], RefreshToken.prototype, "token", void 0);
|
|
56
|
+
__decorate([
|
|
57
|
+
(0, typegoose_1.prop)({ required: true, type: () => String }),
|
|
58
|
+
__metadata("design:type", String)
|
|
59
|
+
], RefreshToken.prototype, "entityId", void 0);
|
|
60
|
+
__decorate([
|
|
61
|
+
(0, typegoose_1.prop)({
|
|
62
|
+
required: true,
|
|
63
|
+
type: () => String,
|
|
64
|
+
enum: index_1.AuthEntityType
|
|
65
|
+
}),
|
|
66
|
+
__metadata("design:type", String)
|
|
67
|
+
], RefreshToken.prototype, "entityType", void 0);
|
|
68
|
+
__decorate([
|
|
69
|
+
(0, typegoose_1.prop)({ required: false, type: () => Date }),
|
|
70
|
+
__metadata("design:type", Object)
|
|
71
|
+
], RefreshToken.prototype, "expiresAt", void 0);
|
|
72
|
+
__decorate([
|
|
73
|
+
(0, typegoose_1.prop)({ required: true, type: () => Boolean, default: false }),
|
|
74
|
+
__metadata("design:type", Boolean)
|
|
75
|
+
], RefreshToken.prototype, "isRevoked", void 0);
|
|
76
|
+
__decorate([
|
|
77
|
+
(0, typegoose_1.prop)({ required: false, type: () => Object }),
|
|
78
|
+
__metadata("design:type", Object)
|
|
79
|
+
], RefreshToken.prototype, "metadata", void 0);
|
|
80
|
+
exports.RefreshToken = RefreshToken = RefreshToken_1 = __decorate([
|
|
81
|
+
(0, typegoose_1.modelOptions)({
|
|
82
|
+
schemaOptions: {
|
|
83
|
+
collection: 'refresh_tokens',
|
|
84
|
+
autoCreate: true,
|
|
85
|
+
toJSON: { virtuals: true },
|
|
86
|
+
toObject: { virtuals: true }
|
|
87
|
+
},
|
|
88
|
+
options: {
|
|
89
|
+
allowMixed: typegoose_1.Severity.ALLOW
|
|
90
|
+
}
|
|
91
|
+
}),
|
|
92
|
+
(0, typegoose_1.index)({ token: 1 }, { unique: true }),
|
|
93
|
+
(0, typegoose_1.index)({ entityId: 1, entityType: 1 }),
|
|
94
|
+
(0, typegoose_1.index)({ isRevoked: 1 })
|
|
95
|
+
], RefreshToken);
|
|
96
|
+
//# sourceMappingURL=refreshtoken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refreshtoken.js","sourceRoot":"/","sources":["libraries/auth/refreshtoken.ts"],"names":[],"mappings":"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","sourcesContent":["import { prop, getModelForClass, modelOptions, index, Severity, DocumentType, ReturnModelType } from '@typegoose/typegoose';\r\nimport { TimeStamps } from '@typegoose/typegoose/lib/defaultClasses';\r\nimport { getLibraries } from '../../index';\r\nimport {AuthEntityType, RefreshTokenModel} from \"./index\";\r\n\r\n@modelOptions({\r\n schemaOptions: {\r\n collection: 'refresh_tokens',\r\n autoCreate: true,\r\n toJSON: { virtuals: true },\r\n toObject: { virtuals: true }\r\n },\r\n options: {\r\n allowMixed: Severity.ALLOW // Allow mixed types for metadata\r\n }\r\n})\r\n@index({ token: 1 }, { unique: true })\r\n@index({ entityId: 1, entityType: 1 })\r\n@index({ isRevoked: 1 })\r\nexport class RefreshToken extends TimeStamps {\r\n @prop({ required: true, type: () => String, unique: true })\r\n public token!: string;\r\n\r\n @prop({ required: true, type: () => String })\r\n public entityId!: string;\r\n\r\n @prop({\r\n required: true,\r\n type: () => String,\r\n enum: AuthEntityType\r\n })\r\n public entityType!: AuthEntityType;\r\n\r\n @prop({ required: false, type: () => Date })\r\n public expiresAt?: Date | null;\r\n\r\n @prop({ required: true, type: () => Boolean, default: false })\r\n public isRevoked!: boolean;\r\n\r\n @prop({ required: false, type: () => Object })\r\n public metadata?: Record<string, unknown>;\r\n\r\n /**\r\n * Static method to find a valid token\r\n */\r\n public static async findValidToken(\r\n this: ReturnModelType<typeof RefreshToken>,\r\n token: string\r\n ): Promise<DocumentType<RefreshToken> | null> {\r\n const query: any = { token, isRevoked: false };\r\n\r\n // Only check expiration if token has an expiration date\r\n query.$or = [\r\n { expiresAt: { $exists: false } },\r\n { expiresAt: null },\r\n { expiresAt: { $gt: new Date() } }\r\n ];\r\n\r\n return this.findOne(query);\r\n }\r\n\r\n /**\r\n * Static method to revoke all tokens for an entity\r\n */\r\n public static async revokeAllForEntity(\r\n this: ReturnModelType<typeof RefreshToken>,\r\n entityId: string,\r\n entityType: AuthEntityType\r\n ): Promise<number> {\r\n const result = await this.updateMany(\r\n { entityId, entityType, isRevoked: false },\r\n { isRevoked: true }\r\n );\r\n\r\n return result.modifiedCount;\r\n }\r\n\r\n /**\r\n * Check if this token is expired\r\n */\r\n public isExpired(): boolean {\r\n if (!this.expiresAt) return false;\r\n return new Date() > this.expiresAt;\r\n }\r\n\r\n /**\r\n * Static method to clean up old expired tokens\r\n * Call this periodically to keep your database clean\r\n */\r\n public static async cleanupExpiredTokens(\r\n this: ReturnModelType<typeof RefreshToken>,\r\n olderThan?: Date\r\n ): Promise<number> {\r\n const cutoffDate = olderThan || new Date();\r\n\r\n const result = await this.deleteMany({\r\n expiresAt: { $ne: null, $lt: cutoffDate },\r\n isRevoked: true // Only delete tokens that are both expired and already revoked\r\n });\r\n\r\n return result.deletedCount;\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AuthEntityType } from "./index";
|
|
2
|
+
import { DocumentType } from "@typegoose/typegoose";
|
|
3
|
+
import { RefreshToken } from "./refreshtoken";
|
|
4
|
+
export declare class TokenRepository {
|
|
5
|
+
saveRefreshToken(token: {
|
|
6
|
+
token: string;
|
|
7
|
+
entityId: string;
|
|
8
|
+
entityType: AuthEntityType;
|
|
9
|
+
expiresAt?: Date | null;
|
|
10
|
+
isRevoked?: boolean;
|
|
11
|
+
metadata?: Record<string, unknown>;
|
|
12
|
+
}): Promise<DocumentType<RefreshToken>>;
|
|
13
|
+
findRefreshToken(token: string): Promise<DocumentType<RefreshToken> | null>;
|
|
14
|
+
revokeRefreshToken(token: string): Promise<boolean>;
|
|
15
|
+
revokeAllRefreshTokensForEntity(entityId: string, entityType: AuthEntityType): Promise<boolean>;
|
|
16
|
+
getActiveTokensForEntity(entityId: string, entityType: AuthEntityType): Promise<DocumentType<RefreshToken>[]>;
|
|
17
|
+
cleanupExpiredTokens(olderThan?: Date): Promise<number>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.TokenRepository = void 0;
|
|
10
|
+
const index_1 = require("./index");
|
|
11
|
+
const typedi_1 = require("typedi");
|
|
12
|
+
let TokenRepository = class TokenRepository {
|
|
13
|
+
async saveRefreshToken(token) {
|
|
14
|
+
return index_1.RefreshTokenModel.create(token);
|
|
15
|
+
}
|
|
16
|
+
async findRefreshToken(token) {
|
|
17
|
+
return index_1.RefreshTokenModel.findValidToken(token);
|
|
18
|
+
}
|
|
19
|
+
async revokeRefreshToken(token) {
|
|
20
|
+
const result = await index_1.RefreshTokenModel.updateOne({ token }, { isRevoked: true });
|
|
21
|
+
return result.modifiedCount > 0;
|
|
22
|
+
}
|
|
23
|
+
async revokeAllRefreshTokensForEntity(entityId, entityType) {
|
|
24
|
+
const count = await index_1.RefreshTokenModel.revokeAllForEntity(entityId, entityType);
|
|
25
|
+
return count > 0;
|
|
26
|
+
}
|
|
27
|
+
async getActiveTokensForEntity(entityId, entityType) {
|
|
28
|
+
return index_1.RefreshTokenModel.find({
|
|
29
|
+
entityId,
|
|
30
|
+
entityType,
|
|
31
|
+
isRevoked: false,
|
|
32
|
+
$or: [
|
|
33
|
+
{ expiresAt: { $exists: false } },
|
|
34
|
+
{ expiresAt: null },
|
|
35
|
+
{ expiresAt: { $gt: new Date() } }
|
|
36
|
+
]
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async cleanupExpiredTokens(olderThan) {
|
|
40
|
+
return index_1.RefreshTokenModel.cleanupExpiredTokens(olderThan);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
exports.TokenRepository = TokenRepository;
|
|
44
|
+
exports.TokenRepository = TokenRepository = __decorate([
|
|
45
|
+
(0, typedi_1.Service)()
|
|
46
|
+
], TokenRepository);
|
|
47
|
+
//# sourceMappingURL=repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"/","sources":["libraries/auth/repository.ts"],"names":[],"mappings":";;;;;;;;;AAAA,mCAA0D;AAG1D,mCAA+B;AAGxB,IAAM,eAAe,GAArB,MAAM,eAAe;IAIxB,KAAK,CAAC,gBAAgB,CAAC,KAOtB;QACG,OAAO,yBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IAKD,KAAK,CAAC,gBAAgB,CAAC,KAAa;QAChC,OAAO,yBAAiB,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACnD,CAAC;IAKD,KAAK,CAAC,kBAAkB,CAAC,KAAa;QAClC,MAAM,MAAM,GAAG,MAAM,yBAAiB,CAAC,SAAS,CAC5C,EAAE,KAAK,EAAE,EACT,EAAE,SAAS,EAAE,IAAI,EAAE,CACtB,CAAC;QAEF,OAAO,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;IACpC,CAAC;IAKD,KAAK,CAAC,+BAA+B,CACjC,QAAgB,EAChB,UAA0B;QAE1B,MAAM,KAAK,GAAG,MAAM,yBAAiB,CAAC,kBAAkB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC/E,OAAO,KAAK,GAAG,CAAC,CAAC;IACrB,CAAC;IAKD,KAAK,CAAC,wBAAwB,CAC1B,QAAgB,EAChB,UAA0B;QAE1B,OAAO,yBAAiB,CAAC,IAAI,CAAC;YAC1B,QAAQ;YACR,UAAU;YACV,SAAS,EAAE,KAAK;YAChB,GAAG,EAAE;gBACD,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;gBACjC,EAAE,SAAS,EAAE,IAAI,EAAE;gBACnB,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE;aACrC;SACJ,CAAC,CAAC;IACP,CAAC;IAMD,KAAK,CAAC,oBAAoB,CAAC,SAAgB;QACvC,OAAO,yBAAiB,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAC7D,CAAC;CACJ,CAAA;AAvEY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,gBAAO,GAAE;GACG,eAAe,CAuE3B","sourcesContent":["import {AuthEntityType, RefreshTokenModel} from \"./index\";\r\nimport {DocumentType} from \"@typegoose/typegoose\";\r\nimport {RefreshToken} from \"./refreshtoken\";\r\nimport {Service} from \"typedi\";\r\n\r\n@Service()\r\nexport class TokenRepository {\r\n /**\r\n * Save a refresh token\r\n */\r\n async saveRefreshToken(token: {\r\n token: string;\r\n entityId: string;\r\n entityType: AuthEntityType;\r\n expiresAt?: Date | null;\r\n isRevoked?: boolean;\r\n metadata?: Record<string, unknown>;\r\n }): Promise<DocumentType<RefreshToken>> {\r\n return RefreshTokenModel.create(token);\r\n }\r\n\r\n /**\r\n * Find a refresh token by its value\r\n */\r\n async findRefreshToken(token: string): Promise<DocumentType<RefreshToken> | null> {\r\n return RefreshTokenModel.findValidToken(token);\r\n }\r\n\r\n /**\r\n * Revoke a specific refresh token\r\n */\r\n async revokeRefreshToken(token: string): Promise<boolean> {\r\n const result = await RefreshTokenModel.updateOne(\r\n { token },\r\n { isRevoked: true }\r\n );\r\n\r\n return result.modifiedCount > 0;\r\n }\r\n\r\n /**\r\n * Revoke all refresh tokens for a specific entity\r\n */\r\n async revokeAllRefreshTokensForEntity(\r\n entityId: string,\r\n entityType: AuthEntityType\r\n ): Promise<boolean> {\r\n const count = await RefreshTokenModel.revokeAllForEntity(entityId, entityType);\r\n return count > 0;\r\n }\r\n\r\n /**\r\n * Get all active tokens for an entity\r\n */\r\n async getActiveTokensForEntity(\r\n entityId: string,\r\n entityType: AuthEntityType\r\n ): Promise<DocumentType<RefreshToken>[]> {\r\n return RefreshTokenModel.find({\r\n entityId,\r\n entityType,\r\n isRevoked: false,\r\n $or: [\r\n { expiresAt: { $exists: false } },\r\n { expiresAt: null },\r\n { expiresAt: { $gt: new Date() } }\r\n ]\r\n });\r\n }\r\n\r\n /**\r\n * Clean up expired tokens (can be called periodically if needed)\r\n * Note: MongoDB TTL index will also handle this automatically for tokens with expiresAt\r\n */\r\n async cleanupExpiredTokens(olderThan?: Date): Promise<number> {\r\n return RefreshTokenModel.cleanupExpiredTokens(olderThan);\r\n }\r\n}\r\n"]}
|
|
@@ -6,6 +6,7 @@ import { RedisService } from "./redis";
|
|
|
6
6
|
import { ConfigurationService } from "./configuration";
|
|
7
7
|
import { UploadService } from "./upload";
|
|
8
8
|
import { FirebaseService } from "./firebase";
|
|
9
|
+
import { TokenRepository } from "./auth/repository";
|
|
9
10
|
export declare class LibraryManager {
|
|
10
11
|
getLogger(): LyxaLogger;
|
|
11
12
|
getMicroServiceDispatcher(): MicroServiceDispatcher;
|
|
@@ -14,6 +15,7 @@ export declare class LibraryManager {
|
|
|
14
15
|
getRedisService(): RedisService;
|
|
15
16
|
getConfigurationService(): ConfigurationService;
|
|
16
17
|
getFirebaseService(): FirebaseService;
|
|
18
|
+
getAuthTokenRepository(): TokenRepository;
|
|
17
19
|
getGlobalUploadService(): UploadService;
|
|
18
20
|
getTenetUploadService(): UploadService;
|
|
19
21
|
}
|
package/dist/libraries/index.js
CHANGED
|
@@ -16,6 +16,7 @@ const redis_1 = require("./redis");
|
|
|
16
16
|
const configuration_1 = require("./configuration");
|
|
17
17
|
const upload_1 = require("./upload");
|
|
18
18
|
const firebase_1 = require("./firebase");
|
|
19
|
+
const repository_1 = require("./auth/repository");
|
|
19
20
|
let LibraryManager = class LibraryManager {
|
|
20
21
|
getLogger() {
|
|
21
22
|
return typedi_1.Container.get(logger_1.LyxaLogger);
|
|
@@ -38,6 +39,9 @@ let LibraryManager = class LibraryManager {
|
|
|
38
39
|
getFirebaseService() {
|
|
39
40
|
return typedi_1.Container.get(firebase_1.FirebaseService);
|
|
40
41
|
}
|
|
42
|
+
getAuthTokenRepository() {
|
|
43
|
+
return typedi_1.Container.get(repository_1.TokenRepository);
|
|
44
|
+
}
|
|
41
45
|
getGlobalUploadService() {
|
|
42
46
|
return new upload_1.UploadService();
|
|
43
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"/","sources":["libraries/index.ts"],"names":[],"mappings":";;;;;;;;;AAAA,mCAA0C;AAC1C,qCAAuC;AACvC,qCAAoC;AACpC,6CAAoD;AACpD,uCAA+C;AAC/C,mCAAqC;AACrC,mDAAqD;AACrD,qCAAuC;AACvC,yCAA2C;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"/","sources":["libraries/index.ts"],"names":[],"mappings":";;;;;;;;;AAAA,mCAA0C;AAC1C,qCAAuC;AACvC,qCAAoC;AACpC,6CAAoD;AACpD,uCAA+C;AAC/C,mCAAqC;AACrC,mDAAqD;AACrD,qCAAuC;AACvC,yCAA2C;AAC3C,kDAAkD;AAG3C,IAAM,cAAc,GAApB,MAAM,cAAc;IAChB,SAAS;QACZ,OAAO,kBAAS,CAAC,GAAG,CAAC,mBAAU,CAAC,CAAC;IACrC,CAAC;IACM,yBAAyB;QAC5B,OAAO,kBAAS,CAAC,GAAG,CAAC,mCAAsB,CAAC,CAAC;IACjD,CAAC;IACM,gBAAgB;QACnB,OAAO,kBAAS,CAAC,GAAG,CAAC,sBAAa,CAAC,CAAC;IACxC,CAAC;IACM,iBAAiB;QACpB,OAAO,kBAAS,CAAC,GAAG,CAAC,8BAAoB,CAAC,CAAC;IAC/C,CAAC;IACM,eAAe;QAClB,OAAO,kBAAS,CAAC,GAAG,CAAC,oBAAY,CAAC,CAAC;IACvC,CAAC;IACM,uBAAuB;QAC1B,OAAO,kBAAS,CAAC,GAAG,CAAC,oCAAoB,CAAC,CAAC;IAC/C,CAAC;IACM,kBAAkB;QACrB,OAAO,kBAAS,CAAC,GAAG,CAAC,0BAAe,CAAC,CAAC;IAC1C,CAAC;IACM,sBAAsB;QACzB,OAAO,kBAAS,CAAC,GAAG,CAAC,4BAAe,CAAC,CAAC;IAC1C,CAAC;IACM,sBAAsB;QACzB,OAAO,IAAI,sBAAa,EAAE,CAAC;IAC/B,CAAC;IACM,qBAAqB;QACxB,OAAO,IAAI,sBAAa,CAAC,OAAO,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACrF,CAAC;CACJ,CAAA;AA/BY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,gBAAO,GAAE;GACG,cAAc,CA+B1B","sourcesContent":["import {Container, Service} from \"typedi\";\r\nimport {TwilioService} from \"./twilio\";\r\nimport {LyxaLogger} from \"./logger\";\r\nimport {MicroServiceDispatcher} from \"./dispatcher\";\r\nimport {SecretManagerService} from \"./secrets\";\r\nimport {RedisService} from \"./redis\";\r\nimport {ConfigurationService} from \"./configuration\";\r\nimport {UploadService} from \"./upload\";\r\nimport {FirebaseService} from \"./firebase\";\r\nimport {TokenRepository} from \"./auth/repository\";\r\n\r\n@Service()\r\nexport class LibraryManager {\r\n public getLogger(): LyxaLogger {\r\n return Container.get(LyxaLogger);\r\n }\r\n public getMicroServiceDispatcher(): MicroServiceDispatcher {\r\n return Container.get(MicroServiceDispatcher);\r\n }\r\n public getTwilioService(): TwilioService {\r\n return Container.get(TwilioService);\r\n }\r\n public getSecretsService(): SecretManagerService {\r\n return Container.get(SecretManagerService);\r\n }\r\n public getRedisService(): RedisService {\r\n return Container.get(RedisService);\r\n }\r\n public getConfigurationService(): ConfigurationService {\r\n return Container.get(ConfigurationService);\r\n }\r\n public getFirebaseService(): FirebaseService {\r\n return Container.get(FirebaseService);\r\n }\r\n public getAuthTokenRepository(): TokenRepository {\r\n return Container.get(TokenRepository);\r\n }\r\n public getGlobalUploadService(): UploadService {\r\n return new UploadService();\r\n }\r\n public getTenetUploadService(): UploadService {\r\n return new UploadService(\"lyxa-\" + this.getConfigurationService().options.tenet);\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { GeoLocationType } from "../../../utilities/enum";
|
|
2
|
+
export declare class Address {
|
|
3
|
+
address: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
city: string;
|
|
6
|
+
state: string;
|
|
7
|
+
country: string;
|
|
8
|
+
geoLocationType: GeoLocationType;
|
|
9
|
+
coordinates: number[];
|
|
10
|
+
latitude: number;
|
|
11
|
+
longitude: number;
|
|
12
|
+
}
|
|
13
|
+
export declare class UserAddress extends Address {
|
|
14
|
+
addressLabel: string;
|
|
15
|
+
apartment: string;
|
|
16
|
+
buildingName: string;
|
|
17
|
+
deliveryOption?: string;
|
|
18
|
+
instructions?: string;
|
|
19
|
+
}
|