| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- import { Database } from "bun:sqlite";
- const authDB = new Database("./data/auth.sqlite");
- authDB.run(`create table if not exists verifications (
- email text not null primary key,
- token text not null,
- code integer not null,
- timestamp datetime default current_timestamp
- );`)
- authDB.run(`create table if not exists users (
- email text not null primary key,
- name text,
- timestamp datetime default current_timestamp
- );`)
- authDB.run(`create table if not exists sessions (
- id text not null primary key,
- secretHash text not null,
- email text not null,
- timestamp datetime default current_timestamp,
- lastAccessed datetime default current_timestamp
- );`)
- import nodemailer from "nodemailer"
- import generateSecureRandomString from "./generateSecureRandomString";
- import generateSecureCode from "./generateSecureCode";
- import hashSecret from "./hashSecret";
- import Meteostanice from "./meteostanice";
- const transporter = nodemailer.createTransport({
- host: process.env.AUTH_EMAIL_SMTP_HOSTNAME,
- port: process.env.AUTH_EMAIL_SMTP_PORT,
- secure: true, // Use true for port 465, false for port 587
- auth: {
- user: process.env.AUTH_EMAIL_SMTP_USERNAME,
- pass: process.env.AUTH_EMAIL_SMTP_PASSWORD,
- },
- });
- export default class Auth {
- static addVerification(email) {
- const token = generateSecureRandomString()
- const code = generateSecureCode()
- authDB.prepare(`
- INSERT INTO verifications (email, token, code)
- VALUES (?, ?, ?)
- ON CONFLICT(email) DO UPDATE SET
- token = excluded.token,
- code = excluded.code;
- `).run(email, token, code)
- return { email, token, code }
- }
- static async sendVerification(email, subject, text, html) {
- return await transporter.sendMail({
- from: process.env.AUTH_EMAIL_SMTP_FROM,
- to: email,
- subject,
- text, // Plain-text version of the message
- html, // HTML version of the message
- });
- }
- static getVerification(token) {
- const statement = authDB.prepare(`
- SELECT *,
- ( CASE
- WHEN (strftime('%s', 'now') - strftime('%s', timestamp)) > $seconds THEN 0
- ELSE 1
- END
- ) AS valid
- FROM verifications
- WHERE token = $token;
- `)
- const result = statement.get({
- $seconds: process.env.EMAIL_VERIFICATION_TIMEOUT,
- $token: token
- });
- return result;
- }
- static removeVerification(token) {
- authDB.prepare(`
- DELETE
- FROM verifications
- WHERE token = ?;
- `).run(token)
- }
- static removeUserVerifications(email) {
- authDB.prepare(`
- DELETE
- FROM verifications
- WHERE email = ?;
- `).run(email)
- }
- static addUser(email) {
- const statement = authDB.prepare("INSERT INTO users (email) VALUES (?);")
- statement.run(
- email
- );
- return { email };
- }
- static getUser(email) {
- const statement = authDB.prepare("select * from users where email = ?;")
- const result = statement.get(
- email
- );
- return result;
- }
- static editUser(email, newName, newEmail) {
- const statement = authDB.prepare("select * from users where email = ?;")
- const user = statement.get(
- email
- );
- if (!user) return null
- const result = authDB.prepare(`
- update users
- set name = ?,
- email = ?
- where email = ?;
- `).run(newName, newEmail, email)
- Meteostanice.editOwnerOnOwned(email, newEmail)
- return result
- }
- static deleteUser(email) {
- Meteostanice.deleteOwned(email)
- this.removeUserSessions(email)
- this.removeUserVerifications(email)
- authDB.prepare(`
- DELETE
- FROM users
- WHERE email = ?;
- `).run(email)
- }
- static async createSession(email) {
- const id = generateSecureRandomString();
- const secret = generateSecureRandomString();
- const secretHash = await hashSecret(secret);
- const token = id + "." + secret;
- const statement = authDB.prepare("INSERT INTO sessions (id, secretHash, email) VALUES (?, ?, ?);")
- statement.run(
- id,
- secretHash,
- email
- );
- return { id, secretHash, token, email };
- }
- static async getSession(token) {
- if (!token) return null
- const [id, secret] = token.split(".")
- const secretHash = await hashSecret(secret)
- const statement = authDB.prepare(`
- SELECT *,
- ( CASE
- WHEN (strftime('%s', 'now') - strftime('%s', lastAccessed)) > $seconds THEN 0
- ELSE 1
- END
- ) AS valid
- FROM sessions
- WHERE id = $id AND secretHash = $secretHash;
- `)
- const result = statement.get({
- $seconds: process.env.SESSION_TIMEOUT,
- $id: id,
- $secretHash: secretHash
- })
- const updateStmt = authDB.prepare(`
- UPDATE sessions
- SET lastAccessed = CURRENT_TIMESTAMP
- WHERE id = $id AND secretHash = $secretHash
- `)
-
- updateStmt.run({
- $id: id,
- $secretHash: secretHash
- })
- return result
- }
- static removeSession(id) {
- authDB.prepare(`
- DELETE
- FROM sessions
- WHERE id = ?;
- `).run(id)
- }
- static removeUserSessions(email) {
- authDB.prepare(`
- DELETE
- FROM sessions
- WHERE email = ?;
- `).run(email)
- }
- }
|