Skip to content

Commit

Permalink
Merge pull request #1534 from CaliOpen/frontend/server-update-iron
Browse files Browse the repository at this point in the history
[frontend] fix server crash
  • Loading branch information
iamdey authored Aug 20, 2021
2 parents baf971c + 5527b32 commit 1870b64
Show file tree
Hide file tree
Showing 18 changed files with 324 additions and 222 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ and this project adheres to
[Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed

- Crash after signup, use a subquery instead.

### Changed

- Redirect to external account configuration after signup.

## [0.24.4] 2021-07-25

### Fixed
Expand Down
5 changes: 4 additions & 1 deletion src/frontend/web_application/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"font-awesome": "^4.6.3",
"foundation-sites": "~6.3.0",
"history": "^4.10.1",
"iron": "4.0.5",
"iron": "5.0.6",
"jquery": "^3.5.0",
"jssha": "^2.3.1",
"linkifyjs": "^2.1.9",
Expand Down Expand Up @@ -124,6 +124,9 @@
"@testing-library/react": "12.0.0",
"@testing-library/user-event": "^13.1.9",
"@types/classnames": "^2.3.1",
"@types/express": "^4.17.13",
"@types/express-http-proxy": "^1.6.2",
"@types/iron": "^5.0.2",
"@types/jest": "^26.0.23",
"@types/lingui__react": "^2.8.3",
"@types/lodash": "^4.14.168",
Expand Down
99 changes: 0 additions & 99 deletions src/frontend/web_application/server/api/lib/api.js

This file was deleted.

108 changes: 108 additions & 0 deletions src/frontend/web_application/server/api/lib/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import http from 'http';
import https from 'https';
import createDebug from 'debug';
import { getConfig } from '../../config';
import { ServerError } from '../../error/consts';

const debug = createDebug('caliopen.web:app:api-query');

type RequestParams = http.RequestOptions | https.RequestOptions;

interface Options {
body?: string | Record<string, any>;
}

/**
* Internal promisified requests.
* This is a basic wrapper that use current host configuration to make requests on the API.
*
* @returns data from response in a Promise
*/
export const query = (
requestParams: RequestParams,
opts: Options = {}
): Promise<string | Array<any> | Record<string, any>> => {
return new Promise((resolve, reject) => {
const {
api: { protocol, hostname, port, checkCertificate },
} = getConfig();
const params = {
protocol: `${protocol}:`,
hostname,
port,
...requestParams,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...(requestParams.headers || {}),
},
};

const options = {
body: undefined,
...opts,
};

let postData: undefined | string;
if (options.body) {
postData = JSON.stringify(options.body);
params.headers['Content-Length'] = Buffer.byteLength(postData);
}

if (!checkCertificate && protocol === 'https') {
// @ts-ignore: this param only exists for `https.RequestOptions`
params.rejectUnauthorized = false;
}

debug('\n', 'Preparing API query:', '\n', params);

const request = protocol === 'https' ? https.request : http.request;
const req = request(params, (res) => {
debug(
'\n',
'API query response:',
'\n',
res.statusCode,
res.statusMessage,
res.headers
);

const data: Array<Buffer> = [];

res.on('data', (chunk) => {
data.push(chunk);
});

res.on('end', () => {
let responseBody = Buffer.concat(data).toString();

if (
res.headers['content-type'] &&
res.headers['content-type'].indexOf('json') !== -1
) {
responseBody = JSON.parse(responseBody);
}

if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
resolve(responseBody);
} else {
const error = new ServerError(
`API Query Error ${res.statusCode} : ${res.statusMessage}`
);
if (res.statusCode) {
error.status = res.statusCode;
}
reject(error);
}
});
});

if (postData) {
req.write(postData);
}

debug('\n', 'Outgoing API query:', '\n', req);

req.end();
});
};
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { encode } from '../lib/seal';
import type { Response } from 'express';

import { encode } from './seal';
import { getConfig } from '../../config';

export const COOKIE_NAME = 'caliopen.web';
Expand All @@ -14,21 +16,20 @@ const getCookieOptions = () => {
return { ...COOKIE_OPTIONS, domain: hostname };
};

export const authenticate = (res, { user }) =>
new Promise((resolve, reject) => {
const {
seal: { secret },
} = getConfig();
export const authenticate = (res: Response, { user }) => {
const {
seal: { secret },
} = getConfig();

encode(user, secret, (err, sealed) => {
if (err || !sealed) {
return reject('Unexpected Error');
}
return encode(user, secret).then(
(sealed) => {
res.cookie(COOKIE_NAME, sealed, getCookieOptions());
},
() => {
return Promise.reject('Unexpected Error');
}
);
};

return resolve();
});
});

export const invalidate = (res) =>
export const invalidate = (res: Response) =>
res.clearCookie(COOKIE_NAME, getCookieOptions());
9 changes: 0 additions & 9 deletions src/frontend/web_application/server/auth/lib/seal.js

This file was deleted.

9 changes: 9 additions & 0 deletions src/frontend/web_application/server/auth/lib/seal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Iron from 'iron';

export function encode(obj: object, secret: string) {
return Iron.seal(obj, secret, Iron.defaults);
}

export function decode(sealed: string, secret: string) {
return Iron.unseal(sealed, secret, Iron.defaults);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import { decode } from '../lib/seal';
import { COOKIE_NAME } from '../lib/cookie';
import { getConfig } from '../../config';

class ResponseError extends Error {
status: number;
err: any;
}

export const decodeCookieMiddleware = (req, res, next) => {
const {
seal: { secret },
Expand All @@ -14,22 +19,23 @@ export const decodeCookieMiddleware = (req, res, next) => {
return;
}

decode(cookie, secret, (err, obj) => {
if (err || !obj) {
const error = new Error('Unexpected Server Error on cookie decoding');
decode(cookie, secret).then(
(obj) => {
req.user = obj;

// TODO: refresh token
// new Date(Date.UTC(req.user.tokens.expires_at)).getTime() < new Date().getTime() + (1000 * 60 * 10)

next();
},
(err) => {
const error = new ResponseError(
'Unexpected Server Error on cookie decoding'
);
error.status = 500;
error.err = err;

next(error);

return;
}

req.user = obj;

// TODO: refresh token
// new Date(Date.UTC(req.user.tokens.expires_at)).getTime() < new Date().getTime() + (1000 * 60 * 10)

next();
});
);
};
Loading

0 comments on commit 1870b64

Please sign in to comment.