diff --git a/client/src/adapters/auth.ts b/client/src/adapters/auth.ts index 5dbde550cd0b01b26df3a6c66138459de4641edc..48198a66d066bf82d844922c4e9f870d20a4e540 100644 --- a/client/src/adapters/auth.ts +++ b/client/src/adapters/auth.ts @@ -37,7 +37,7 @@ async function extendAccessToken() { if (response.ok) { const json = await response.json(); setToken(json.token); - } else if (response.status === 403) { + } else { clearToken(); } } catch(e) { diff --git a/client/src/config.ts b/client/src/config.ts index 38c8d39c67e67d3c160d59ad6e398406abdeb632..f7959fd9c4c74fbb54ca2116f8e95c33efdcde17 100644 --- a/client/src/config.ts +++ b/client/src/config.ts @@ -1,3 +1,9 @@ -export const apiRoot = `${window.location.origin}/v1`; +export let apiRoot: string; + +if (process.env.NODE_ENV === 'production') { + apiRoot = `${window.location.origin}/v1`; +} else { + apiRoot = `http://localhost:8000/v1`; +} diff --git a/server/src/config.ts b/server/src/config.ts index 26fd98f447e9cad3fdbf8db5d0fd6c5346e72246..0e758a19ab66213d1c2dcf892ac34c82b22d2270 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -6,6 +6,7 @@ export const port = env.PORT ?? 8000; export const keys = { private: './keys/cert.key', public: './keys/cert.pem', + secret: 'SECRET', }; export const allowedOrigins = [ "*" ]; diff --git a/server/src/keys.ts b/server/src/keys.ts index 96e0edfb50554afd9e5333c1dfafd2dd19e66ee3..0c28f6b51e3190b2318398d6bbcfd7f37e660ee0 100644 --- a/server/src/keys.ts +++ b/server/src/keys.ts @@ -3,6 +3,25 @@ import { readFileBuffer } from './util'; import { env } from 'process'; import { keys } from './config'; +let hasKeys: boolean | null = null; + +export async function usePublicAndPrivate(): Promise<boolean> { + if (hasKeys === null) { + try { + await getPrivateKey(); + await getPublicKey(); + hasKeys = true; + } catch(e) { + hasKeys = false; + } + } + return hasKeys; +} + +export function getSecret(): string { + return keys.secret; +} + let privateKey: string; export async function getPrivateKey(): Promise<string> { diff --git a/server/src/knexconfig.ts b/server/src/knexconfig.ts index 7f5a5030b168e6ef2bc5c57aac571a7073005cbe..66f12382c2c193d850168b9caeeded6e57a46b0d 100644 --- a/server/src/knexconfig.ts +++ b/server/src/knexconfig.ts @@ -3,7 +3,7 @@ import { env } from 'process'; import { join } from 'path'; import { parse } from 'pg-connection-string'; -const pgconfig: any = parse(env.DATABASE_URL ?? ''); +const pgconfig: any = parse(env.DATABASE_URL ?? 'postgresql://postgres@localhost/ryoko'); export default { development: { diff --git a/server/src/v1/auth.ts b/server/src/v1/auth.ts index eb667d293338fd973919b0371344f54cd757e519..01418d90734901ade0d755566899cbe3306312fb 100644 --- a/server/src/v1/auth.ts +++ b/server/src/v1/auth.ts @@ -6,7 +6,7 @@ import { sign, verify } from 'jsonwebtoken'; import database from '../database'; import { isOfType, asyncify } from '../util'; -import { getPublicKey, getPrivateKey } from '../keys'; +import { getPublicKey, getPrivateKey, getSecret, usePublicAndPrivate } from '../keys'; const auth = express(); @@ -31,9 +31,13 @@ export async function tokenVerification(req: Request, _res: Response, next: Next if (token) { delete req.body.token; try { - const decoded = await asyncify(verify, token, await getPublicKey(), { algorithms: ["ES384"] }); - if (isOfType<Token>(decoded, [['id', 'string'], ['type', 'string']]) && decoded.type === authTokenType) { - req.body.token = decoded; + if (await usePublicAndPrivate()) { + const decoded = await asyncify(verify, token, await getPublicKey(), { algorithms: ["ES384"] }); + if (isOfType<Token>(decoded, [['id', 'string'], ['type', 'string']]) && decoded.type === authTokenType) { + req.body.token = decoded; + } + } else { + return asyncify(verify, token, getSecret(), { algorithms: ["HS384"] }); } } catch (err) { /* Token has already been deleted */ } next(); @@ -58,7 +62,11 @@ async function generateAuthToken(id: string) { id: id, type: authTokenType, }; - return asyncify(sign, token, await getPrivateKey(), { algorithm: "ES384", expiresIn: 60 * 60 }); + if (await usePublicAndPrivate()) { + return asyncify(sign, token, await getPrivateKey(), { algorithm: "ES384", expiresIn: 60 * 60 }); + } else { + return asyncify(sign, token, getSecret(), { algorithm: "HS384", expiresIn: 60 * 60 }); + } } interface RegisterBody {