feat(auth): Switch scanstation auth from argon2 to sha256 to improve performance
This commit is contained in:
@@ -4,11 +4,12 @@ import { CountryCode } from 'libphonenumber-js';
|
|||||||
import ValidatorJS from 'validator';
|
import ValidatorJS from 'validator';
|
||||||
|
|
||||||
configDotenv();
|
configDotenv();
|
||||||
export const config = {
|
export const config = {
|
||||||
internal_port: parseInt(process.env.APP_PORT) || 4010,
|
internal_port: parseInt(process.env.APP_PORT) || 4010,
|
||||||
development: process.env.NODE_ENV === "production",
|
development: process.env.NODE_ENV === "production",
|
||||||
testing: process.env.NODE_ENV === "test",
|
testing: process.env.NODE_ENV === "test",
|
||||||
jwt_secret: process.env.JWT_SECRET || "secretjwtsecret",
|
jwt_secret: process.env.JWT_SECRET || "secretjwtsecret",
|
||||||
|
station_token_secret: process.env.STATION_TOKEN_SECRET || "",
|
||||||
phone_validation_countrycode: getPhoneCodeLocale(),
|
phone_validation_countrycode: getPhoneCodeLocale(),
|
||||||
postalcode_validation_countrycode: getPostalCodeLocale(),
|
postalcode_validation_countrycode: getPostalCodeLocale(),
|
||||||
version: process.env.VERSION || require('../package.json').version,
|
version: process.env.VERSION || require('../package.json').version,
|
||||||
@@ -28,10 +29,14 @@ if (typeof config.development !== "boolean") {
|
|||||||
consola.error("Error: NODE_ENV is not a boolean")
|
consola.error("Error: NODE_ENV is not a boolean")
|
||||||
errors++
|
errors++
|
||||||
}
|
}
|
||||||
if (config.mailer_url == "" || config.mailer_key == "") {
|
if (config.mailer_url == "" || config.mailer_key == "") {
|
||||||
consola.error("Error: invalid mailer config")
|
consola.error("Error: invalid mailer config")
|
||||||
errors++;
|
errors++;
|
||||||
}
|
}
|
||||||
|
if (config.station_token_secret.length < 32) {
|
||||||
|
consola.error("Error: STATION_TOKEN_SECRET must be set and at least 32 characters long")
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
function getPhoneCodeLocale(): CountryCode {
|
function getPhoneCodeLocale(): CountryCode {
|
||||||
return (process.env.PHONE_COUNTRYCODE as CountryCode);
|
return (process.env.PHONE_COUNTRYCODE as CountryCode);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { verify } from '@node-rs/argon2';
|
import crypto from 'crypto';
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { getConnectionManager } from 'typeorm';
|
import { getConnectionManager } from 'typeorm';
|
||||||
|
import { config } from '../config';
|
||||||
import { ScanStation } from '../models/entities/ScanStation';
|
import { ScanStation } from '../models/entities/ScanStation';
|
||||||
import authchecker from './authchecker';
|
import authchecker from './authchecker';
|
||||||
|
|
||||||
@@ -57,8 +58,12 @@ const ScanAuth = async (req: Request, res: Response, next: () => void) => {
|
|||||||
else {
|
else {
|
||||||
if (station.enabled == false) {
|
if (station.enabled == false) {
|
||||||
res.status(401).send({ http_code: 401, short: "station_disabled", message: "Station is disabled." });
|
res.status(401).send({ http_code: 401, short: "station_disabled", message: "Station is disabled." });
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (!(await verify(station.key, provided_token))) {
|
const expectedHash = crypto.createHmac("sha256", config.station_token_secret).update(provided_token).digest('hex');
|
||||||
|
const expectedHashBuf = Buffer.from(expectedHash);
|
||||||
|
const providedHashBuf = Buffer.from(station.key);
|
||||||
|
if (expectedHashBuf.length !== providedHashBuf.length || !crypto.timingSafeEqual(expectedHashBuf, providedHashBuf)) {
|
||||||
res.status(401).send({ http_code: 401, short: "invalid_token", message: "Api token non-existent or invalid syntax." });
|
res.status(401).send({ http_code: 401, short: "invalid_token", message: "Api token non-existent or invalid syntax." });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { hash } from '@node-rs/argon2';
|
|
||||||
import { IsBoolean, IsInt, IsOptional, IsPositive, IsString } from 'class-validator';
|
import { IsBoolean, IsInt, IsOptional, IsPositive, IsString } from 'class-validator';
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import { getConnection } from 'typeorm';
|
import { getConnection } from 'typeorm';
|
||||||
import * as uuid from 'uuid';
|
import * as uuid from 'uuid';
|
||||||
|
import { config } from '../../../config';
|
||||||
import { TrackNotFoundError } from '../../../errors/TrackErrors';
|
import { TrackNotFoundError } from '../../../errors/TrackErrors';
|
||||||
import { ScanStation } from '../../entities/ScanStation';
|
import { ScanStation } from '../../entities/ScanStation';
|
||||||
import { Track } from '../../entities/Track';
|
import { Track } from '../../entities/Track';
|
||||||
@@ -44,8 +44,8 @@ export class CreateScanStation {
|
|||||||
|
|
||||||
let newUUID = uuid.v4().toUpperCase();
|
let newUUID = uuid.v4().toUpperCase();
|
||||||
newStation.prefix = crypto.createHash("sha3-512").update(newUUID).digest('hex').substring(0, 7).toUpperCase();
|
newStation.prefix = crypto.createHash("sha3-512").update(newUUID).digest('hex').substring(0, 7).toUpperCase();
|
||||||
newStation.key = await hash(newStation.prefix + "." + newUUID);
|
|
||||||
newStation.cleartextkey = newStation.prefix + "." + newUUID;
|
newStation.cleartextkey = newStation.prefix + "." + newUUID;
|
||||||
|
newStation.key = crypto.createHmac("sha256", config.station_token_secret).update(newStation.cleartextkey).digest('hex');
|
||||||
|
|
||||||
return newStation;
|
return newStation;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user