Skip to content

Commit 5612188

Browse files
authored
Merge pull request #196 from bcgov/chore/release
Release COMS v0.6
2 parents f027eab + 00915fa commit 5612188

File tree

11 files changed

+5961
-6102
lines changed

11 files changed

+5961
-6102
lines changed

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88
# Build the application
99
#
10-
FROM registry.access.redhat.com/ubi9/nodejs-18:1-48 as builder
10+
FROM registry.access.redhat.com/ubi9/nodejs-18:1-59 as builder
1111

1212
ENV NO_UPDATE_NOTIFIER=true
1313

@@ -22,7 +22,7 @@ RUN npm ci --omit=dev
2222
#
2323
# Create the final container image
2424
#
25-
FROM registry.access.redhat.com/ubi9/nodejs-18-minimal:1-51
25+
FROM registry.access.redhat.com/ubi9/nodejs-18-minimal:1-63
2626

2727
ENV APP_PORT=3000 \
2828
NO_UPDATE_NOTIFIER=true

SECURITY.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ At this time, only the latest version of Common Object Management Service is sup
1414

1515
| Version | Supported |
1616
| ------- | ------------------ |
17-
| 0.5.0 | :white_check_mark: |
18-
| < 0.5.x | :x: |
17+
| 0.6.0 | :white_check_mark: |
18+
| < 0.6.x | :x: |
1919

2020
## Reporting a Bug
2121

app/app.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,11 @@ switch (state.authMode) {
5353
break;
5454
}
5555
if (state.authMode === AuthMode.OIDCAUTH || state.authMode === AuthMode.FULLAUTH) {
56-
// Use Keycloak OIDC Middleware
57-
const keycloak = require('./src/components/keycloak');
58-
app.use(keycloak.middleware());
56+
if (!config.has('keycloak.publicKey')) {
57+
log.error('OIDC environment variable KC_PUBLICKEY or keycloak.publicKey must be defined');
58+
process.exitCode = 1;
59+
shutdown();
60+
}
5961
}
6062

6163
// Application privacy Mode mode

app/package-lock.json

Lines changed: 5910 additions & 6024 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/package.json

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "common-object-management-service",
3-
"version": "0.5.0",
3+
"version": "0.6.0",
44
"private": true,
55
"description": "",
66
"author": "NR Common Service Showcase <NR.CommonServiceShowcase@gov.bc.ca>",
@@ -29,9 +29,9 @@
2929
"seed": "knex seed:run"
3030
},
3131
"dependencies": {
32-
"@aws-sdk/client-s3": "^3.341.0",
33-
"@aws-sdk/lib-storage": "^3.341.0",
34-
"@aws-sdk/s3-request-presigner": "^3.341.0",
32+
"@aws-sdk/client-s3": "^3.388.0",
33+
"@aws-sdk/lib-storage": "^3.388.0",
34+
"@aws-sdk/s3-request-presigner": "^3.388.0",
3535
"api-problem": "^9.0.1",
3636
"busboy": "^1.6.0",
3737
"compression": "^1.7.4",
@@ -44,23 +44,22 @@
4444
"express-validation": "^4.1.0",
4545
"express-winston": "^4.2.0",
4646
"js-yaml": "^4.1.0",
47-
"jsonwebtoken": "^9.0.0",
48-
"keycloak-connect": "^21.0.1",
49-
"knex": "^2.4.2",
50-
"objection": "^3.0.1",
51-
"pg": "^8.11.0",
52-
"winston": "^3.9.0",
47+
"jsonwebtoken": "^9.0.1",
48+
"knex": "^2.5.1",
49+
"objection": "^3.1.1",
50+
"pg": "^8.11.2",
51+
"winston": "^3.10.0",
5352
"winston-transport": "^4.5.0"
5453
},
5554
"devDependencies": {
56-
"aws-sdk-client-mock": "^2.1.1",
57-
"aws-sdk-client-mock-jest": "^2.1.1",
58-
"eslint": "^8.41.0",
55+
"aws-sdk-client-mock": "^3.0.0",
56+
"aws-sdk-client-mock-jest": "^3.0.0",
57+
"eslint": "^8.47.0",
5958
"eslint-config-recommended": "^4.1.0",
60-
"eslint-plugin-prettier": "^4.2.1",
59+
"eslint-plugin-prettier": "^5.0.0",
6160
"jest": "~29.3.1",
6261
"jest-joi": "^1.1.17",
63-
"nodemon": "^2.0.22",
62+
"nodemon": "^3.0.1",
6463
"supertest": "^6.3.3"
6564
}
6665
}

app/src/components/keycloak.js

Lines changed: 0 additions & 21 deletions
This file was deleted.

app/src/db/models/mixins/encrypt.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ const Encrypt = opts => {
3939
await super.$afterUpdate(queryOptions, context);
4040
return this.decryptFields();
4141
}
42-
async $afterGet(context) {
43-
await super.$afterGet(context);
42+
async $afterFind(context) {
43+
await super.$afterFind(context);
4444
return this.decryptFields();
4545
}
4646

app/src/middleware/authentication.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ const currentUser = async (req, res, next) => {
7474
issuer: `${config.get('keycloak.serverUrl')}/realms/${config.get('keycloak.realm')}`
7575
});
7676
} else {
77-
const keycloak = require('../components/keycloak');
78-
isValid = await keycloak.grantManager.validateAccessToken(bearerToken);
77+
throw new Error('OIDC environment variable KC_PUBLICKEY or keycloak.publicKey must be defined');
7978
}
8079

8180
if (isValid) {

app/tests/unit/middleware/authentication.spec.js

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ const jwt = require('jsonwebtoken');
44

55
const mw = require('../../../src/middleware/authentication');
66
const { AuthType } = require('../../../src/components/constants');
7-
const keycloak = require('../../../src/components/keycloak');
87
const { userService } = require('../../../src/services');
98

109
// Mock config library - @see {@link https://stackoverflow.com/a/64819698}
@@ -17,8 +16,6 @@ jest.mock('express-basic-auth', () => {
1716
buildMiddleware.safeCompare = jest.requireActual('express-basic-auth').safeCompare;
1817
return buildMiddleware;
1918
});
20-
// Mock out keycloak library and use a spy to observe behavior
21-
jest.mock('../../../src/components/keycloak');
2219

2320
beforeEach(() => {
2421
jest.resetAllMocks();
@@ -90,7 +87,6 @@ describe('currentUser', () => {
9087
const jwtVerifySpy = jest.spyOn(jwt, 'verify');
9188
const loginSpy = jest.spyOn(userService, 'login');
9289
const problemSendSpy = jest.spyOn(Problem.prototype, 'send');
93-
const validateAccessTokenSpy = jest.spyOn(keycloak.grantManager, 'validateAccessToken');
9490

9591
let req, res, next;
9692

@@ -159,7 +155,7 @@ describe('currentUser', () => {
159155
it.each([
160156
['SPKI', spki],
161157
['PEM', publicKey]
162-
])('sets authType to BEARER with keycloak.publicKey %s', async (_desc, pkey) => {
158+
])('sets authType to BEARER with keycloak.publicKey %s and valid auth token', async (_desc, pkey) => {
163159
jwtVerifySpy.mockReturnValue({ sub: 'sub' }); // return truthy value
164160
loginSpy.mockImplementation(() => { });
165161
config.has
@@ -187,7 +183,6 @@ describe('currentUser', () => {
187183
expect(config.get).toHaveBeenNthCalledWith(1, 'keycloak.publicKey');
188184
expect(config.get).toHaveBeenNthCalledWith(2, 'keycloak.serverUrl');
189185
expect(config.get).toHaveBeenNthCalledWith(3, 'keycloak.realm');
190-
expect(validateAccessTokenSpy).toHaveBeenCalledTimes(0);
191186
expect(checkBasicAuthSpy).toHaveBeenCalledTimes(0);
192187
expect(jwtVerifySpy).toHaveBeenCalledTimes(1);
193188
expect(jwtVerifySpy).toHaveBeenCalledWith(expect.any(String), publicKey, expect.objectContaining({
@@ -200,42 +195,43 @@ describe('currentUser', () => {
200195
expect(problemSendSpy).toHaveBeenCalledTimes(0);
201196
});
202197

203-
it('sets authType to BEARER without keycloak.publicKey and valid token', async () => {
204-
jwtVerifySpy.mockReturnValue({ sub: 'sub' });
205-
loginSpy.mockImplementation(() => { });
206-
validateAccessTokenSpy.mockResolvedValue('tokenstring');
198+
it('short circuits with invalid auth token', async () => {
199+
const authorization = 'bearer ';
200+
201+
problemSendSpy.mockImplementation(() => { });
207202
config.has
208203
.mockReturnValueOnce(false) // basicAuth.enabled
209204
.mockReturnValueOnce(true) // keycloak.enabled
210-
.mockReturnValueOnce(false); // keycloak.publicKey
205+
.mockReturnValueOnce(true); // keycloak.publicKey
206+
config.get
207+
.mockReturnValueOnce(spki) // keycloak.publicKey
208+
.mockReturnValueOnce(serverUrl) // keycloak.serverUrl
209+
.mockReturnValueOnce(realm); // keycloak.realm
211210
req.get.mockReturnValueOnce(authorization);
212211

213212
await mw.currentUser(req, res, next);
214213

215-
expect(req.currentUser).toBeTruthy();
216-
expect(req.currentUser).toHaveProperty('authType', AuthType.BEARER);
217-
expect(req.currentUser).toHaveProperty('tokenPayload');
214+
expect(req.currentUser).toBeFalsy();
218215
expect(req.get).toHaveBeenCalledTimes(1);
219216
expect(req.get).toHaveBeenCalledWith('Authorization');
220217
expect(config.has).toHaveBeenCalledTimes(3);
221218
expect(config.has).toHaveBeenNthCalledWith(1, 'basicAuth.enabled');
222219
expect(config.has).toHaveBeenNthCalledWith(2, 'keycloak.enabled');
223220
expect(config.has).toHaveBeenNthCalledWith(3, 'keycloak.publicKey');
224-
expect(validateAccessTokenSpy).toHaveBeenCalledTimes(1);
225-
expect(validateAccessTokenSpy).toHaveBeenCalledWith(expect.any(String));
226221
expect(checkBasicAuthSpy).toHaveBeenCalledTimes(0);
227-
expect(jwtVerifySpy).toHaveBeenCalledTimes(0);
228-
expect(loginSpy).toHaveBeenCalledTimes(1);
229-
expect(next).toHaveBeenCalledTimes(1);
230-
expect(next).toHaveBeenCalledWith();
231-
expect(problemSendSpy).toHaveBeenCalledTimes(0);
222+
expect(jwtVerifySpy).toHaveBeenCalledTimes(1);
223+
expect(jwtVerifySpy).toHaveBeenCalledWith(expect.any(String), publicKey, expect.objectContaining({
224+
issuer: `${serverUrl}/realms/${realm}`
225+
}));
226+
expect(loginSpy).toHaveBeenCalledTimes(0);
227+
expect(next).toHaveBeenCalledTimes(0);
228+
expect(problemSendSpy).toHaveBeenCalledTimes(1);
229+
expect(problemSendSpy).toHaveBeenCalledWith(res);
232230
});
233231

234-
it('short circuits without keycloak.publicKey and invalid token', async () => {
235-
const authorization = 'bearer ';
236-
237-
problemSendSpy.mockImplementation(() => { });
238-
validateAccessTokenSpy.mockResolvedValue(false);
232+
it('short circuits without keycloak.publicKey', async () => {
233+
jwtVerifySpy.mockReturnValue({ sub: 'sub' });
234+
loginSpy.mockImplementation(() => { });
239235
config.has
240236
.mockReturnValueOnce(false) // basicAuth.enabled
241237
.mockReturnValueOnce(true) // keycloak.enabled
@@ -251,8 +247,6 @@ describe('currentUser', () => {
251247
expect(config.has).toHaveBeenNthCalledWith(1, 'basicAuth.enabled');
252248
expect(config.has).toHaveBeenNthCalledWith(2, 'keycloak.enabled');
253249
expect(config.has).toHaveBeenNthCalledWith(3, 'keycloak.publicKey');
254-
expect(validateAccessTokenSpy).toHaveBeenCalledTimes(1);
255-
expect(validateAccessTokenSpy).toHaveBeenCalledWith(expect.any(String));
256250
expect(checkBasicAuthSpy).toHaveBeenCalledTimes(0);
257251
expect(jwtVerifySpy).toHaveBeenCalledTimes(0);
258252
expect(loginSpy).toHaveBeenCalledTimes(0);

charts/coms/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: common-object-management-service
33
# This is the chart version. This version number should be incremented each time you make changes
44
# to the chart and its templates, including the app version.
55
# Versions are expected to follow Semantic Versioning (https://semver.org/)
6-
version: 0.0.16
6+
version: 0.0.17
77
kubeVersion: ">= 1.13.0"
88
description: A microservice for managing access control to S3 Objects
99
# A chart can be either an 'application' or a 'library' chart.
@@ -43,6 +43,6 @@ maintainers:
4343
# incremented each time you make changes to the application. Versions are not expected to
4444
# follow Semantic Versioning. They should reflect the version the application is using.
4545
# It is recommended to use it with quotes.
46-
appVersion: "0.5.0"
46+
appVersion: "0.6.0"
4747
deprecated: false
4848
annotations: {}

0 commit comments

Comments
 (0)