Skip to content

Commit

Permalink
Copy node-utils into ltiapi, improve logging, remove bad tests (#2756)
Browse files Browse the repository at this point in the history
* give local copy of node-utils to ltiapi, log more, remove bad tests

* fix ci
  • Loading branch information
emmachughes authored Aug 16, 2024
1 parent 0a28c3a commit 2f435bd
Show file tree
Hide file tree
Showing 100 changed files with 3,228 additions and 4,249 deletions.
22 changes: 0 additions & 22 deletions .github/workflows/api-lti.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,8 @@ env:
workingDirectory: sourcecode/apis/lti

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Use Node.js 16
uses: actions/setup-node@v3
with:
node-version: 16

- name: "Yarn install with cache"
uses: bahmutov/npm-install@v1
with:
working-directory: ${{ env.workingDirectory }}

- name: "Run tests"
run: cd ${{ env.workingDirectory }}; node node_modules/jest/bin/jest.js --runInBand --colors --verbose --forceExit --config=./jest.config.json
shell: bash

create_release:
runs-on: ubuntu-latest
needs: test
if: ${{ inputs.versionToRelease }}
steps:
- uses: actions/checkout@v3
Expand Down
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ services:
condition: service_healthy
rabbitmq:
condition: service_healthy
redis:
condition: service_healthy
command: [sh, -c, 'update-ca-certificates && yarn && yarn migrate && yarn dev']
healthcheck:
test: [CMD, curl, -f, "http://localhost/_ah/health"]
Expand Down
13 changes: 0 additions & 13 deletions sourcecode/apis/lti/babel.config.cjs

This file was deleted.

26 changes: 21 additions & 5 deletions sourcecode/apis/lti/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,34 @@
"node": ">= 16.0.0"
},
"dependencies": {
"@babel/preset-env": "^7.20.2",
"@cerpus/edlib-node-utils": "1.11.0",
"@hapi/joi": "^17.1.1",
"amqplib": "^0.8.0",
"babel-plugin-transform-default-import": "^1.0.0",
"jest": "^27.5.1",
"await-lock": "^2.2.2",
"axios": "^0.27.2",
"better-sqlite3": "^8.1.0",
"body-parser": "^1.19.2",
"cookie-parser": "^1.4.5",
"dotenv": "^15.0.0",
"dotenv-expand": "^8.0.3",
"express": "^4.18.2",
"helmet": "^5.1.0",
"joi": "^17.8.3",
"js-yaml": "^4.1.0",
"jsonwebtoken": "^8.5.1",
"jwks-rsa": "^2.1.4",
"knex": "^1.0.7",
"lodash": "^4.17.21",
"moment-timezone": "^0.5.40",
"mysql": "^2.18.1",
"on-finished": "^2.4.1",
"prettier": "^2.8.4",
"redis": "^4.5.0",
"redis-mock": "^0.56.3",
"supertest": "^6.3.3",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^4.6.2",
"uuid": "^8.3.2"
"uuid": "^8.3.2",
"winston": "^3.8.2"
},
"devDependencies": {
"nodemon": "^2.0.20"
Expand Down
20 changes: 0 additions & 20 deletions sourcecode/apis/lti/src/__tests__/readiness.js

This file was deleted.

3 changes: 1 addition & 2 deletions sourcecode/apis/lti/src/api.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { setupApi } from '@cerpus/edlib-node-utils';
import { pubsub, setupApi } from './node-utils/index.js';
import router from './routes/index.js';
import { pubsub } from '@cerpus/edlib-node-utils';

const start = async () => {
const pubSubConnection = await pubsub.setup();
Expand Down
2 changes: 1 addition & 1 deletion sourcecode/apis/lti/src/config/apis.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { env } from '@cerpus/edlib-node-utils';
import { env } from '../node-utils/index.js';

export default {
coreInternal: {
Expand Down
2 changes: 1 addition & 1 deletion sourcecode/apis/lti/src/config/app.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { config, env } from '@cerpus/edlib-node-utils';
import { config, env } from '../node-utils/index.js';

export default {
isProduction: config.app.isProduction,
Expand Down
2 changes: 1 addition & 1 deletion sourcecode/apis/lti/src/context/services/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { apiClients } from '@cerpus/edlib-node-utils';
import { apiClients } from '../../node-utils/index.js';
import apiConfig from '../../config/apis.js';
import resource from './resource.js';

Expand Down
3 changes: 1 addition & 2 deletions sourcecode/apis/lti/src/context/services/resource.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import apis from '../../config/apis.js';
import axios from 'axios';
import { exceptionTranslator } from '@cerpus/edlib-node-utils';
import { NotFoundException } from '@cerpus/edlib-node-utils';
import { exceptionTranslator, NotFoundException } from '../../node-utils/index.js';

const resourceAxios = async (options) => {
try {
Expand Down
2 changes: 1 addition & 1 deletion sourcecode/apis/lti/src/controllers/consumer.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NotFoundException } from '@cerpus/edlib-node-utils';
import { NotFoundException } from '../node-utils/index.js';

export default {
getConsumerByKey: async (req) => {
Expand Down
2 changes: 1 addition & 1 deletion sourcecode/apis/lti/src/controllers/job.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NotFoundException, pubsub } from '@cerpus/edlib-node-utils';
import { NotFoundException, pubsub } from '../node-utils/index.js';
import jobNames from '../constants/jobNames.js';

export default {
Expand Down
3 changes: 1 addition & 2 deletions sourcecode/apis/lti/src/controllers/lti.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import Joi from 'joi';
import { validateJoi } from '@cerpus/edlib-node-utils';
import { NotFoundException } from '@cerpus/edlib-node-utils';
import { validateJoi, NotFoundException } from '../node-utils/index.js';
import appConfig from '../config/app.js';

export default {
Expand Down
2 changes: 1 addition & 1 deletion sourcecode/apis/lti/src/controllers/usageView.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NotFoundException, validateJoi } from '@cerpus/edlib-node-utils';
import { NotFoundException, validateJoi } from '../node-utils/index.js';
import Joi from 'joi';

export default {
Expand Down

This file was deleted.

131 changes: 131 additions & 0 deletions sourcecode/apis/lti/src/node-utils/apiClients/auth/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import axios from 'axios';
import AwaitLock from 'await-lock';
import moment from 'moment';
import logger from '../../services/logger.js';
import * as errorReporting from '../../services/errorReporting.js';
import { verifyTokenAgainstAuth } from '../../services/auth.js';

let cachedToken = null;
let jwksClients = {};

const createAuthAxios = (req, config) => async (options) =>
axios({
...options,
url: `${config.url}${options.url}`,
maxRedirects: 0,
headers: {
...options.headers,
...errorReporting.getTraceHeaders(req),
},
});

const authMutex = AwaitLock.default ? new AwaitLock.default() : new AwaitLock();

export default (req, config) => {
const authAxios = createAuthAxios(req, config);

const loginCallback = async (code, redirectUrl) => {
const response = await authAxios({
url: `/oauth/token?client_id=${config.clientId}&code=${code}&redirect_uri=${redirectUrl}&grant_type=authorization_code`,
method: 'GET',
headers: {
Authorization: `Basic ${Buffer.from(
`${config.clientId}:${config.secret}`
).toString('base64')}`,
},
});

return response.data;
};

const generateJwt = async (accessToken) => {
const response = await authAxios({
url: `/v1/jwt/create`,
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
},
});

return response.data;
};

const refreshJwt = async (accessToken) => {
const response = await authAxios({
url: `/v2/jwt/refresh`,
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
},
});

return response.data;
};

const identity = async (token) => {
const response = await authAxios({
url: `/v1/identity?access_token=${token}`,
method: 'GET',
});

return response.data;
};

const getOAuthToken = async (bypassCache = false) => {
await authMutex.acquireAsync();

if (
!bypassCache &&
cachedToken &&
cachedToken.expiresAt.isAfter(moment())
) {
authMutex.release();
return cachedToken.access_token;
}

logger.info(
`Fetching new oauth server to server token from ${config.url}`
);

try {
const authResponse = await axios({
url: `${config.url}/oauth/token`,
method: 'POST',
headers: {
authorization: `Basic ${new Buffer(
`${config.clientId}:${config.secret}`
).toString('base64')}`,
},
params: { grant_type: 'client_credentials' },
});

cachedToken = {
...authResponse.data,
expiresAt: moment().add(
authResponse.data.expires_in - 60 * 2, // subtract 2 minutes in seconds to have a margin
'seconds'
),
};
} catch (e) {
authMutex.release();
throw e;
}

authMutex.release();

return cachedToken.access_token;
};

return {
loginCallback,
identity,
getOAuthToken,
generateJwt,
refreshJwt,
verifyTokenAgainstAuth: verifyTokenAgainstAuth(
jwksClients,
`${config.url}/.well-known/jwks.json`
),
config,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export default (core) => {
const create = async (authorizationJwt, type, ltiExtraParameters) => {
return (
await core({
url: `/v2/contentauthor/create${type ? `/${type}` : ''}`,
method: 'POST',
authorizationJwt,
data: ltiExtraParameters,
})
).data;
};

const edit = async (
authorizationJwt,
resourceId,
translateToLanguage,
launchPresentationLocale
) => {
return (
await core({
url: `/v2/contentauthor/edit/${resourceId}`,
method: 'POST',
authorizationJwt,
data: {
translateLanguage: translateToLanguage || undefined,
launchPresentationLocale,
},
})
).data;
};

return {
create,
edit,
};
};
Loading

0 comments on commit 2f435bd

Please sign in to comment.