@flowerforce/flowerbase 1.7.3-beta.1 → 1.7.3-beta.2
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/auth/plugins/jwt.d.ts.map +1 -1
- package/dist/auth/plugins/jwt.js +11 -5
- package/dist/utils/context/helpers.d.ts +1 -1
- package/dist/utils/context/helpers.d.ts.map +1 -1
- package/dist/utils/context/helpers.js +4 -3
- package/package.json +1 -1
- package/src/auth/plugins/jwt.test.ts +22 -1
- package/src/auth/plugins/jwt.ts +12 -5
- package/src/utils/__tests__/contextExecuteCompatibility.test.ts +34 -0
- package/src/utils/context/helpers.ts +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../src/auth/plugins/jwt.ts"],"names":[],"mappings":"AAKA,KAAK,OAAO,GAAG;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;
|
|
1
|
+
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../src/auth/plugins/jwt.ts"],"names":[],"mappings":"AAKA,KAAK,OAAO,GAAG;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAeD;;;;;;;GAOG;iUAC8C,OAAO;AAAxD,wBA4GE"}
|
package/dist/auth/plugins/jwt.js
CHANGED
|
@@ -16,6 +16,12 @@ const jwt_1 = __importDefault(require("@fastify/jwt"));
|
|
|
16
16
|
const fastify_plugin_1 = __importDefault(require("fastify-plugin"));
|
|
17
17
|
const mongodb_1 = require("mongodb");
|
|
18
18
|
const constants_1 = require("../../constants");
|
|
19
|
+
const unauthorizedSessionError = {
|
|
20
|
+
message: 'Unauthorized',
|
|
21
|
+
error: 'unauthorized',
|
|
22
|
+
errorCode: 'InvalidSession',
|
|
23
|
+
error_code: 'InvalidSession'
|
|
24
|
+
};
|
|
19
25
|
/**
|
|
20
26
|
* This module is a Fastify plugin that sets up JWT-based authentication and token creation.
|
|
21
27
|
* It registers JWT authentication, and provides methods to create access and refresh tokens.
|
|
@@ -38,7 +44,7 @@ exports.default = (0, fastify_plugin_1.default)(function (fastify, opts) {
|
|
|
38
44
|
}
|
|
39
45
|
catch (err) {
|
|
40
46
|
fastify.log.warn({ err }, 'JWT authentication failed');
|
|
41
|
-
reply.code(401).send(
|
|
47
|
+
reply.code(401).send(unauthorizedSessionError);
|
|
42
48
|
return;
|
|
43
49
|
}
|
|
44
50
|
if (((_a = request.user) === null || _a === void 0 ? void 0 : _a.typ) !== 'access') {
|
|
@@ -50,7 +56,7 @@ exports.default = (0, fastify_plugin_1.default)(function (fastify, opts) {
|
|
|
50
56
|
return;
|
|
51
57
|
}
|
|
52
58
|
if (!request.user.sub) {
|
|
53
|
-
reply.code(401).send(
|
|
59
|
+
reply.code(401).send(unauthorizedSessionError);
|
|
54
60
|
return;
|
|
55
61
|
}
|
|
56
62
|
let authUser;
|
|
@@ -61,11 +67,11 @@ exports.default = (0, fastify_plugin_1.default)(function (fastify, opts) {
|
|
|
61
67
|
}
|
|
62
68
|
catch (err) {
|
|
63
69
|
fastify.log.warn({ err }, 'Failed to lookup user during JWT authentication');
|
|
64
|
-
reply.code(401).send(
|
|
70
|
+
reply.code(401).send(unauthorizedSessionError);
|
|
65
71
|
return;
|
|
66
72
|
}
|
|
67
73
|
if (!authUser) {
|
|
68
|
-
reply.code(401).send(
|
|
74
|
+
reply.code(401).send(unauthorizedSessionError);
|
|
69
75
|
return;
|
|
70
76
|
}
|
|
71
77
|
const lastLogoutAt = authUser.lastLogoutAt ? new Date(authUser.lastLogoutAt) : null;
|
|
@@ -81,7 +87,7 @@ exports.default = (0, fastify_plugin_1.default)(function (fastify, opts) {
|
|
|
81
87
|
typeof issuedAt === 'number' &&
|
|
82
88
|
!Number.isNaN(issuedAt) &&
|
|
83
89
|
lastLogoutAt.getTime() >= issuedAt * 1000) {
|
|
84
|
-
reply.code(401).send(
|
|
90
|
+
reply.code(401).send(unauthorizedSessionError);
|
|
85
91
|
return;
|
|
86
92
|
}
|
|
87
93
|
});
|
|
@@ -15,7 +15,7 @@ type JwtUtils = {
|
|
|
15
15
|
* @param currentFunction -> the function's name that should be called
|
|
16
16
|
* @param functionsList -> the list of all functions
|
|
17
17
|
*/
|
|
18
|
-
export declare const generateContextData: ({ user, services, app, rules, currentFunction, functionName, functionsList,
|
|
18
|
+
export declare const generateContextData: ({ user, services, app, rules, currentFunction, functionName, functionsList, GenerateContextSync, request }: GenerateContextDataParams) => {
|
|
19
19
|
BSON: typeof mongodb.BSON;
|
|
20
20
|
EJSON: {
|
|
21
21
|
parse: (text: string, options?: mongodb.BSON.EJSONOptions) => any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/context/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/context/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAG1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEvD,KAAK,QAAQ,GAAG;IACd,MAAM,EAAE,CACN,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACzC,MAAM,CAAA;IACX,MAAM,EAAE,CACN,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GAAG,MAAM,EACpB,YAAY,CAAC,EAAE,OAAO,EACtB,sBAAsB,CAAC,EAAE,MAAM,EAAE,KAC9B,OAAO,CAAA;CACb,CAAA;AAgFD;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,4GAUjC,yBAAyB;;;;;;;;;;;;;uBA4DP,SAAS;yBAGP,SAAS;;;;;;;;;;;;;;;;;;uBAcb,MAAM;;;;;;+BA5CU,MAAM,OAAO,QAAQ;;;;sCA1HrC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAsGT,CAAC;iCAAa,CAAC;;;;;;;;;;;;;;;;;;;kCAtGP,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAsGT,CAAC;6BAAa,CAAC;;;;;;;;;;;;;;;;;;kCAtGP,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAsGT,CAAC;6BAAa,CAAC;;;;;;;;;;;;;;;4BAyEF,MAAM,OAAO,aAAa,WAAW,SAAS;;;CAiBrE,CAAA"}
|
|
@@ -35,8 +35,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.generateContextData = void 0;
|
|
37
37
|
const mongodb_1 = require("@fastify/mongodb");
|
|
38
|
-
const jwt = __importStar(require("jsonwebtoken"));
|
|
39
38
|
const bson_1 = require("bson");
|
|
39
|
+
const jwt = __importStar(require("jsonwebtoken"));
|
|
40
40
|
const normalizePayload = (payload) => {
|
|
41
41
|
if (typeof payload !== 'string')
|
|
42
42
|
return payload;
|
|
@@ -108,7 +108,7 @@ const createJwtUtils = () => {
|
|
|
108
108
|
* @param currentFunction -> the function's name that should be called
|
|
109
109
|
* @param functionsList -> the list of all functions
|
|
110
110
|
*/
|
|
111
|
-
const generateContextData = ({ user, services, app, rules, currentFunction, functionName, functionsList,
|
|
111
|
+
const generateContextData = ({ user, services, app, rules, currentFunction, functionName, functionsList, GenerateContextSync, request }) => {
|
|
112
112
|
var _a;
|
|
113
113
|
const BSON = mongodb_1.mongodb.BSON;
|
|
114
114
|
const Binary = BSON === null || BSON === void 0 ? void 0 : BSON.Binary;
|
|
@@ -185,7 +185,8 @@ const generateContextData = ({ user, services, app, rules, currentFunction, func
|
|
|
185
185
|
currentFunction,
|
|
186
186
|
functionName: String(name),
|
|
187
187
|
functionsList,
|
|
188
|
-
services
|
|
188
|
+
services,
|
|
189
|
+
deserializeArgs: false
|
|
189
190
|
});
|
|
190
191
|
}
|
|
191
192
|
}
|
package/package.json
CHANGED
|
@@ -40,6 +40,13 @@ describe('jwtAuthentication', () => {
|
|
|
40
40
|
await app.close()
|
|
41
41
|
})
|
|
42
42
|
|
|
43
|
+
const unauthorizedSessionError = {
|
|
44
|
+
message: 'Unauthorized',
|
|
45
|
+
error: 'unauthorized',
|
|
46
|
+
errorCode: 'InvalidSession',
|
|
47
|
+
error_code: 'InvalidSession'
|
|
48
|
+
}
|
|
49
|
+
|
|
43
50
|
const setupMongo = (userPayload: { _id: ObjectId; lastLogoutAt?: Date }) => {
|
|
44
51
|
const findOneMock = jest.fn().mockResolvedValue(userPayload)
|
|
45
52
|
const collectionMock = { findOne: findOneMock }
|
|
@@ -88,6 +95,20 @@ describe('jwtAuthentication', () => {
|
|
|
88
95
|
await app.jwtAuthentication(request as any, reply)
|
|
89
96
|
|
|
90
97
|
expect(reply.code).toHaveBeenCalledWith(401)
|
|
91
|
-
expect(reply.send).toHaveBeenCalledWith(
|
|
98
|
+
expect(reply.send).toHaveBeenCalledWith(unauthorizedSessionError)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('returns Realm-compatible unauthorized payload when jwt verification fails', async () => {
|
|
102
|
+
const request = {
|
|
103
|
+
jwtVerify: jest.fn(async () => {
|
|
104
|
+
throw new Error('jwt expired')
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
const reply = createReply()
|
|
108
|
+
|
|
109
|
+
await app.jwtAuthentication(request as any, reply)
|
|
110
|
+
|
|
111
|
+
expect(reply.code).toHaveBeenCalledWith(401)
|
|
112
|
+
expect(reply.send).toHaveBeenCalledWith(unauthorizedSessionError)
|
|
92
113
|
})
|
|
93
114
|
})
|
package/src/auth/plugins/jwt.ts
CHANGED
|
@@ -13,6 +13,13 @@ type JwtAccessWithTimestamp = {
|
|
|
13
13
|
iat?: number
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
const unauthorizedSessionError = {
|
|
17
|
+
message: 'Unauthorized',
|
|
18
|
+
error: 'unauthorized',
|
|
19
|
+
errorCode: 'InvalidSession',
|
|
20
|
+
error_code: 'InvalidSession'
|
|
21
|
+
} as const
|
|
22
|
+
|
|
16
23
|
/**
|
|
17
24
|
* This module is a Fastify plugin that sets up JWT-based authentication and token creation.
|
|
18
25
|
* It registers JWT authentication, and provides methods to create access and refresh tokens.
|
|
@@ -33,7 +40,7 @@ export default fp(async function (fastify, opts: Options) {
|
|
|
33
40
|
await request.jwtVerify()
|
|
34
41
|
} catch (err) {
|
|
35
42
|
fastify.log.warn({ err }, 'JWT authentication failed')
|
|
36
|
-
reply.code(401).send(
|
|
43
|
+
reply.code(401).send(unauthorizedSessionError)
|
|
37
44
|
return
|
|
38
45
|
}
|
|
39
46
|
|
|
@@ -48,7 +55,7 @@ export default fp(async function (fastify, opts: Options) {
|
|
|
48
55
|
}
|
|
49
56
|
|
|
50
57
|
if (!request.user.sub) {
|
|
51
|
-
reply.code(401).send(
|
|
58
|
+
reply.code(401).send(unauthorizedSessionError)
|
|
52
59
|
return
|
|
53
60
|
}
|
|
54
61
|
|
|
@@ -59,12 +66,12 @@ export default fp(async function (fastify, opts: Options) {
|
|
|
59
66
|
.findOne({ _id: new ObjectId(request.user.sub) })
|
|
60
67
|
} catch (err) {
|
|
61
68
|
fastify.log.warn({ err }, 'Failed to lookup user during JWT authentication')
|
|
62
|
-
reply.code(401).send(
|
|
69
|
+
reply.code(401).send(unauthorizedSessionError)
|
|
63
70
|
return
|
|
64
71
|
}
|
|
65
72
|
|
|
66
73
|
if (!authUser) {
|
|
67
|
-
reply.code(401).send(
|
|
74
|
+
reply.code(401).send(unauthorizedSessionError)
|
|
68
75
|
return
|
|
69
76
|
}
|
|
70
77
|
|
|
@@ -84,7 +91,7 @@ export default fp(async function (fastify, opts: Options) {
|
|
|
84
91
|
!Number.isNaN(issuedAt) &&
|
|
85
92
|
lastLogoutAt.getTime() >= issuedAt * 1000
|
|
86
93
|
) {
|
|
87
|
-
reply.code(401).send(
|
|
94
|
+
reply.code(401).send(unauthorizedSessionError)
|
|
88
95
|
return
|
|
89
96
|
}
|
|
90
97
|
})
|
|
@@ -57,4 +57,38 @@ describe('context.functions.execute compatibility', () => {
|
|
|
57
57
|
expect(result && typeof (result as Promise<unknown>).then).toBe('function')
|
|
58
58
|
await expect(result).resolves.toEqual({ ok: true })
|
|
59
59
|
})
|
|
60
|
+
|
|
61
|
+
it('passes circular native objects without EJSON deserialization', () => {
|
|
62
|
+
const functionsList = {
|
|
63
|
+
caller: {
|
|
64
|
+
code: `
|
|
65
|
+
module.exports = function() {
|
|
66
|
+
const session = { tx: true }
|
|
67
|
+
session.client = { sessionPool: { client: session } }
|
|
68
|
+
return context.functions.execute("target", session)
|
|
69
|
+
}
|
|
70
|
+
`
|
|
71
|
+
},
|
|
72
|
+
target: {
|
|
73
|
+
code: `
|
|
74
|
+
module.exports = function(session) {
|
|
75
|
+
return session.client.sessionPool.client === session
|
|
76
|
+
}
|
|
77
|
+
`
|
|
78
|
+
}
|
|
79
|
+
} as Functions
|
|
80
|
+
|
|
81
|
+
const result = GenerateContextSync({
|
|
82
|
+
args: [],
|
|
83
|
+
app: {} as any,
|
|
84
|
+
rules: {} as any,
|
|
85
|
+
user: {} as any,
|
|
86
|
+
currentFunction: functionsList.caller,
|
|
87
|
+
functionsList,
|
|
88
|
+
services: mockServices,
|
|
89
|
+
functionName: 'caller'
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
expect(result).toBe(true)
|
|
93
|
+
})
|
|
60
94
|
})
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { mongodb } from '@fastify/mongodb'
|
|
2
|
+
import { EJSON } from 'bson'
|
|
2
3
|
import * as jwt from 'jsonwebtoken'
|
|
3
4
|
import { Arguments } from '../../auth/dtos'
|
|
4
5
|
import { Function } from '../../features/functions/interface'
|
|
5
6
|
import { GenerateContextDataParams } from './interface'
|
|
6
|
-
import { EJSON } from 'bson'
|
|
7
7
|
|
|
8
8
|
type JwtUtils = {
|
|
9
9
|
encode: (
|
|
@@ -116,7 +116,6 @@ export const generateContextData = ({
|
|
|
116
116
|
currentFunction,
|
|
117
117
|
functionName,
|
|
118
118
|
functionsList,
|
|
119
|
-
GenerateContext,
|
|
120
119
|
GenerateContextSync,
|
|
121
120
|
request
|
|
122
121
|
}: GenerateContextDataParams) => {
|
|
@@ -215,7 +214,8 @@ export const generateContextData = ({
|
|
|
215
214
|
currentFunction,
|
|
216
215
|
functionName: String(name),
|
|
217
216
|
functionsList,
|
|
218
|
-
services
|
|
217
|
+
services,
|
|
218
|
+
deserializeArgs: false
|
|
219
219
|
})
|
|
220
220
|
}
|
|
221
221
|
}
|