proper authentication

This commit is contained in:
Lea 2024-01-16 22:56:19 +01:00
parent 2bf719d1e3
commit eb0cfdad71
Signed by: Lea
GPG key ID: 1BAFFE8347019C42
5 changed files with 830 additions and 36 deletions

3
.env
View file

@ -1 +1,2 @@
NEXTAUTH_SECRET=changeme
NEXTAUTH_SECRET=changeme
CREDENTIALS_DB_PATH=/home/lea/Downloads/credentials.db

View file

@ -10,10 +10,13 @@
},
"dependencies": {
"@radix-ui/themes": "^2.0.3",
"@types/bcryptjs": "^2.4.6",
"bcryptjs": "^2.4.3",
"next": "14.0.4",
"next-auth": "^4.24.5",
"react": "^18",
"react-dom": "^18"
"react-dom": "^18",
"sqlite3": "^5.1.7"
},
"devDependencies": {
"@types/node": "^20",

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,7 @@
import NextAuth from "next-auth";
import CredentialProvider from "next-auth/providers/credentials";
import { sha256sum } from "@/lib/util";
import { validateCredentials } from "@/lib/db";
export const authOptions = {
providers: [
@ -11,18 +12,12 @@ export const authOptions = {
password: { label: "Password", type: "password" },
},
async authorize(credentials, req) {
console.log(`Authentication attempt for ${credentials?.email}`);
console.log(`[${credentials?.email}] Authentication attempt`);
// todo
if (credentials?.email == "balls@fortnite.org" && credentials.password == "ballsack obliteration") {
if (credentials && await validateCredentials(credentials.email, credentials.password)) {
console.log(`[${credentials.email}] Authentication succeeded`);
const emailHash = sha256sum(credentials.email.trim().toLowerCase());
// todo fetch name from gravatar (why not)
//const res = await fetch(`https://gravatar.com/${emailHash}`).catch(() => null);
//const profile = await res?.json().catch(() => null);
return {
id: credentials.email,
email: credentials.email,

34
src/lib/db.ts Normal file
View file

@ -0,0 +1,34 @@
import sqlite from "sqlite3";
import bcrypt from "bcryptjs";
const { CREDENTIALS_DB_PATH } = process.env;
if (!CREDENTIALS_DB_PATH) {
throw "$CREDENTIALS_DB_PATH not provided; unable to connect to database";
}
const database = () => new sqlite.Database(CREDENTIALS_DB_PATH!);
export function validateCredentials(email: string, password: string) {
const db = database();
return new Promise<boolean>((resolve, reject) => {
db.get(
"SELECT key, value FROM passwords WHERE key = ?",
email,
async (err, row: any) => {
db.close(); // We don't need this anymore
if (err) return reject(err);
if (!row) return resolve(false);
try {
const hash: string = row.value.replace("bcrypt:", "");
const isValid = await bcrypt.compare(password, hash);
resolve(isValid);
} catch(e) {
reject(e);
}
}
);
});
}