mirror of
https://github.com/kremalicious/umami.git
synced 2024-11-22 09:57:00 +01:00
Changed JWT implementation.
This commit is contained in:
parent
cb0c912c5b
commit
f3f0ad15f2
@ -1,9 +1,10 @@
|
|||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import { v5 } from 'uuid';
|
import { v5 } from 'uuid';
|
||||||
import jwt from 'jsonwebtoken';
|
|
||||||
import bcrypt from 'bcrypt';
|
import bcrypt from 'bcrypt';
|
||||||
|
import { JWT, JWE, JWK } from 'jose';
|
||||||
|
|
||||||
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
||||||
|
const KEY = JWK.asKey(Buffer.from(secret()));
|
||||||
|
|
||||||
export function sha256(...args) {
|
export function sha256(...args) {
|
||||||
return crypto.createHash('sha256').update(args.join('')).digest('hex');
|
return crypto.createHash('sha256').update(args.join('')).digest('hex');
|
||||||
@ -25,14 +26,23 @@ export function isValidHash(s) {
|
|||||||
return UUID_REGEX.test(s);
|
return UUID_REGEX.test(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createToken(payload, options) {
|
|
||||||
return jwt.sign(payload, secret(), options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function parseToken(token, options) {
|
|
||||||
return jwt.verify(token, secret(), options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function checkPassword(password, hash) {
|
export function checkPassword(password, hash) {
|
||||||
return bcrypt.compare(password, hash);
|
return bcrypt.compare(password, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function createToken(payload) {
|
||||||
|
return JWT.sign(payload, KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function verifyToken(token) {
|
||||||
|
return JWT.verify(token, KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createSecureToken(payload) {
|
||||||
|
return JWE.encrypt(await createToken(payload), KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function verifySecureToken(token) {
|
||||||
|
const result = await JWE.decrypt(token, KEY);
|
||||||
|
return verifyToken(result.toString());
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { getWebsite, getSession, createSession } from 'lib/db';
|
import { getWebsite, getSession, createSession } from 'lib/db';
|
||||||
import { getCountry, getDevice, getIpAddress } from 'lib/utils';
|
import { getCountry, getDevice, getIpAddress } from 'lib/utils';
|
||||||
import { uuid, parseToken, isValidHash } from 'lib/crypto';
|
import { uuid, isValidHash, verifyToken } from 'lib/crypto';
|
||||||
|
|
||||||
export default async req => {
|
export default async req => {
|
||||||
const { payload } = req.body;
|
const { payload } = req.body;
|
||||||
@ -11,7 +11,7 @@ export default async req => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await parseToken(session);
|
return await verifyToken(session);
|
||||||
} catch {
|
} catch {
|
||||||
const ip = getIpAddress(req);
|
const ip = getIpAddress(req);
|
||||||
const { userAgent, browser, os } = getDevice(req);
|
const { userAgent, browser, os } = getDevice(req);
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"geolite2-redist": "^1.0.7",
|
"geolite2-redist": "^1.0.7",
|
||||||
"is-localhost-ip": "^1.4.0",
|
"is-localhost-ip": "^1.4.0",
|
||||||
|
"jose": "^1.27.2",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"maxmind": "^4.1.3",
|
"maxmind": "^4.1.3",
|
||||||
"next": "9.3.5",
|
"next": "9.3.5",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { serialize } from 'cookie';
|
import { serialize } from 'cookie';
|
||||||
import { checkPassword, createToken, secret } from 'lib/crypto';
|
import { checkPassword, createSecureToken } from 'lib/crypto';
|
||||||
import { getAccount } from 'lib/db';
|
import { getAccount } from 'lib/db';
|
||||||
|
|
||||||
export default async (req, res) => {
|
export default async (req, res) => {
|
||||||
@ -9,7 +9,7 @@ export default async (req, res) => {
|
|||||||
|
|
||||||
if (account && (await checkPassword(password, account.password))) {
|
if (account && (await checkPassword(password, account.password))) {
|
||||||
const { user_id, username, is_admin } = account;
|
const { user_id, username, is_admin } = account;
|
||||||
const token = await createToken({ user_id, username, is_admin });
|
const token = await createSecureToken({ user_id, username, is_admin });
|
||||||
const expires = new Date(Date.now() + 31536000000);
|
const expires = new Date(Date.now() + 31536000000);
|
||||||
const cookie = serialize('umami.auth', token, { expires, httpOnly: true });
|
const cookie = serialize('umami.auth', token, { expires, httpOnly: true });
|
||||||
|
|
||||||
|
12
pages/api/verify.js
Normal file
12
pages/api/verify.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { verifySecureToken } from 'lib/crypto';
|
||||||
|
|
||||||
|
export default async (req, res) => {
|
||||||
|
const { token } = req.body;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const payload = await verifySecureToken(token);
|
||||||
|
res.status(200).send(payload);
|
||||||
|
} catch {
|
||||||
|
res.status(400).send('');
|
||||||
|
}
|
||||||
|
};
|
12
yarn.lock
12
yarn.lock
@ -1175,6 +1175,11 @@
|
|||||||
"@nodelib/fs.scandir" "2.1.3"
|
"@nodelib/fs.scandir" "2.1.3"
|
||||||
fastq "^1.6.0"
|
fastq "^1.6.0"
|
||||||
|
|
||||||
|
"@panva/asn1.js@^1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@panva/asn1.js/-/asn1.js-1.0.0.tgz#dd55ae7b8129e02049f009408b97c61ccf9032f6"
|
||||||
|
integrity sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==
|
||||||
|
|
||||||
"@prisma/cli@2.2.2":
|
"@prisma/cli@2.2.2":
|
||||||
version "2.2.2"
|
version "2.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/@prisma/cli/-/cli-2.2.2.tgz#9689483442277523b5724abdafde69f15b8279f0"
|
resolved "https://registry.yarnpkg.com/@prisma/cli/-/cli-2.2.2.tgz#9689483442277523b5724abdafde69f15b8279f0"
|
||||||
@ -4740,6 +4745,13 @@ jest-worker@^26.0.0:
|
|||||||
merge-stream "^2.0.0"
|
merge-stream "^2.0.0"
|
||||||
supports-color "^7.0.0"
|
supports-color "^7.0.0"
|
||||||
|
|
||||||
|
jose@^1.27.2:
|
||||||
|
version "1.27.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/jose/-/jose-1.27.2.tgz#060c6cddf17e90eaa6316b926860b12ab76580fc"
|
||||||
|
integrity sha512-zLIwnMa8dh5A2jFo56KvhiXCaW0hFjdNvG0I5GScL8Wro+/r/SnyIYTbnX3fYztPNSfgQp56sDMHUuS9c3e6bw==
|
||||||
|
dependencies:
|
||||||
|
"@panva/asn1.js" "^1.0.0"
|
||||||
|
|
||||||
js-levenshtein@^1.1.3:
|
js-levenshtein@^1.1.3:
|
||||||
version "1.1.6"
|
version "1.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d"
|
resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d"
|
||||||
|
Loading…
Reference in New Issue
Block a user