idk
This commit is contained in:
parent
349ad6356a
commit
25606bd438
@ -6,21 +6,39 @@ import { authenticator } from 'otplib';
|
||||
const user = new User();
|
||||
|
||||
const userController = new Elysia()
|
||||
.get('/', ({user}) => {
|
||||
return user
|
||||
})
|
||||
.post('/login', async ({ body }) => {
|
||||
const msg = db.query(`select id, password, otp from users WHERE username = ?;`)
|
||||
const msg = db.query(`select id, password, administrator, otp from users WHERE username = ?;`)
|
||||
.get(body.username)
|
||||
console.log(msg)
|
||||
if(msg == null) return new Response("Invalid username or password", { status: 401 })
|
||||
const validPassword = await Bun.password.verify(body.password, msg.password)
|
||||
if (!validPassword) return new Response("Invalid username or password", { status: 401 })
|
||||
// if(!authenticator.check(body.otp, msg.otp)) return new Response("Invalid OTP code", { status: 401 })
|
||||
if(msg.administrator == 1) {return new Response(await user.createToken(msg.id), {status: 418})}
|
||||
return await user.createToken(msg.id)
|
||||
})
|
||||
.post('/register', async({body}) => {
|
||||
return await Bun.password.hash(body.password);
|
||||
})
|
||||
// .post('/register', async({body}) => {
|
||||
// return await Bun.password.hash(body.password);
|
||||
// })
|
||||
.get('/otp', () => {
|
||||
return authenticator.generateSecret();
|
||||
})
|
||||
.put('/password', ({user}, body) => {
|
||||
const oldPassword = body.oldPassword;
|
||||
const newPassword = body.newPassword;
|
||||
if (oldPassword == "" || newPassword == "") {
|
||||
{return new Response("Bad password", {status: 400})}
|
||||
}
|
||||
|
||||
const msg = db.query(`select password from users WHERE id = ?;`).get(user.id);
|
||||
if(!Bun.password.verify(oldPassword, msg.password)) {
|
||||
{return new Response("Bad old password", {status: 400})}
|
||||
}
|
||||
const newPasswordHash = Bun.password.hash(body.newPassword)
|
||||
const msg = db.query(`update users set password = ? WHERE id = ?;`).run(newPassword. user.id);
|
||||
})
|
||||
|
||||
export default userController
|
||||
|
@ -1,10 +1,48 @@
|
||||
import { Elysia } from 'elysia'
|
||||
import db from '../Database'
|
||||
import { authenticator } from 'otplib';
|
||||
|
||||
const adminController = new Elysia()
|
||||
.get('/', () => "admin endpoint")
|
||||
.post('/register', async({body}) => {
|
||||
return await Bun.password.hash(body.password);
|
||||
.get('/users', () => {
|
||||
const users = db.query(`SELECT id, username, name FROM users;`)
|
||||
.all();
|
||||
return users
|
||||
})
|
||||
.post('/user/group/:groupId', ({params: {groupId}, body}) => {
|
||||
db.query(`INSERT INTO userGroups (UserID, GroupID) VALUES (?, ?);`).run(groupId, body.userId);
|
||||
return "Added user to group"
|
||||
})
|
||||
.delete('/user/:userId', ({params: {userId}}) => {
|
||||
db.query(`DELETE FROM users WHERE id = ?;`).run(userId);
|
||||
|
||||
"deleted user"
|
||||
})
|
||||
.post('/register', async({body}) => {
|
||||
const password = await Bun.password.hash(body.password);
|
||||
const otp = authenticator.generateSecret();
|
||||
const res = db.query(`INSERT INTO users(username, password, name, otp) VALUES (?, ?, ?, ?);`).run(body.username, password, body.name, otp);
|
||||
return {id: res.lastInsertRowid, username: body.username, name: body.name, otp: otp}
|
||||
})
|
||||
.get('/group', () => {
|
||||
const groups = db.query(`SELECT GroupID, GroupName FROM groups;`)
|
||||
.all();
|
||||
return groups
|
||||
})
|
||||
.post('/group', ({body}) => {
|
||||
const res = db.query(`INSERT INTO groups (GroupName) VALUES (?);`).run(body.name);
|
||||
return {GroupID: res.lastInsertRowid, GroupName: body.name}
|
||||
})
|
||||
.delete('/group/:groupId', ({ params: { groupId }}) => {
|
||||
db.query(`DELETE FROM groups WHERE GroupID = ?;`).run(groupId);
|
||||
|
||||
"deleted group"
|
||||
})
|
||||
.delete('/password/:passwordId', ({params: {passwordId}}) => {
|
||||
db.query(`DELETE FROM passwords WHERE id = ?;`).run(passwordId);
|
||||
|
||||
"deleted password"
|
||||
})
|
||||
|
||||
|
||||
export default adminController
|
Binary file not shown.
@ -1,9 +1,41 @@
|
||||
import {Elysia} from 'elysia'
|
||||
import userController from './User/Controller'
|
||||
import adminController from './admin/Controller'
|
||||
import passwordController from './password/Controller'
|
||||
import type { User } from './interfaces/user_interface'
|
||||
import db from './Database'
|
||||
import { cors } from '@elysiajs/cors'
|
||||
|
||||
const app = new Elysia()
|
||||
.get('/', () => "Hello")
|
||||
.derive(async ({ headers }) => {
|
||||
const auth = headers['authorization']
|
||||
if (!auth) {
|
||||
return {}
|
||||
}
|
||||
const bearer = auth?.startsWith('Bearer ') ? auth.slice(7) : null
|
||||
|
||||
|
||||
const msg = db.query(`select users.id, users.name, users.administrator from users JOIN tokens ON users.id = tokens.user_id WHERE tokens.token = ?;`)
|
||||
.get(bearer)
|
||||
console.log(msg)
|
||||
if(msg == null) {
|
||||
throw new Response("Invalid token", { status: 401 })
|
||||
return {}
|
||||
}
|
||||
|
||||
const user: User = {
|
||||
id: msg.id,
|
||||
username: msg.username,
|
||||
name: msg.name,
|
||||
admin: msg.administrator
|
||||
}
|
||||
return { user }
|
||||
|
||||
// return user here instead of bearer
|
||||
})
|
||||
.get('/', ({ user }) => user)
|
||||
.group('/user', (app) => app.use(userController))
|
||||
.group('/admin', (app) => app.use(adminController))
|
||||
.group('/password', (app) => app.use(passwordController))
|
||||
.use(cors())
|
||||
.listen(3000)
|
7
backend/src/interfaces/user_interface.ts
Normal file
7
backend/src/interfaces/user_interface.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export type User = {
|
||||
id: number,
|
||||
name: string,
|
||||
username: string,
|
||||
password?: string,
|
||||
admin: boolean,
|
||||
}
|
@ -9,6 +9,7 @@
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@elysiajs/cors": "^1.1.1",
|
||||
"elysia": "^1.1.12",
|
||||
"kysely": "^0.27.4",
|
||||
"nanoid": "^5.0.7",
|
||||
|
44
backend/src/password/Controller.ts
Normal file
44
backend/src/password/Controller.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { Elysia } from 'elysia'
|
||||
import db from '../Database'
|
||||
|
||||
|
||||
const passwordController = new Elysia()
|
||||
.get('/', ({ user }) => {
|
||||
const userGroup = db.query(`SELECT groups.GroupId, groups.GroupName FROM groups JOIN userGroups ON groups.GroupID = userGroups.GroupID JOIN users ON userGroups.UserID = users.id WHERE users.id = ?;`)
|
||||
.all(user.id);
|
||||
return userGroup
|
||||
})
|
||||
.get('/:groupId', ({params: {groupId}}) => {
|
||||
// make sure user has access to group
|
||||
const passwords = db.query(`SELECT id, name, password, created_by, created_at from passwords WHERE group_id = ?;`)
|
||||
.all(groupId);
|
||||
console.log(passwords)
|
||||
return passwords
|
||||
})
|
||||
.post('/:groupId', async({params: {groupId}, body, user}) => {
|
||||
const passName = body.name;
|
||||
const password = body.password
|
||||
|
||||
if (!passName || passName.trim() === "") {
|
||||
return new Response("Name must be defined", { status: 400 });
|
||||
}
|
||||
|
||||
const userGroup = db.query(`SELECT 1 FROM userGroups WHERE userID = ? AND groupID = ?;`)
|
||||
.get(user.id, groupId);
|
||||
|
||||
if (!userGroup) {
|
||||
return new Response("Forbidden: You do not have access to this group", { status: 403 });
|
||||
}
|
||||
|
||||
db.query(`INSERT INTO passwords (name, password, group_id, created_by) VALUES (?, ?, ?, ?);`).run(body.name, body.password, groupId, user.name);
|
||||
|
||||
|
||||
return new Response("Password created successfully", { status: 201 });
|
||||
})
|
||||
.delete('/:passwordId', ({params: {passwordId}}) => {
|
||||
db.query(`DELETE FROM users WHERE id = ?;`).run(userId);
|
||||
|
||||
"deleted password"
|
||||
})
|
||||
|
||||
export default passwordController
|
0
backend/src/utils/groups.ts
Normal file
0
backend/src/utils/groups.ts
Normal file
51
backend/src/utils/send_mail.ts
Normal file
51
backend/src/utils/send_mail.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { SmtpClient } from 'smtp'
|
||||
import config from "../email_config.json" assert { type: "json" };
|
||||
|
||||
const client = new SmtpClient();
|
||||
|
||||
export async function SendVerificationMail(userEmail: string, name: string, companyName: string, verificationToken: string) {
|
||||
try {
|
||||
await client.connect({
|
||||
hostname: config.smtp_server,
|
||||
port: config.smtp_port,
|
||||
username: config.smtp_username,
|
||||
password: config.smtp_password,
|
||||
});
|
||||
|
||||
await client.send({
|
||||
from: "PasswordBox <no-reply@passwordbox.dk>",
|
||||
to: userEmail,
|
||||
subject: "=?utf-8?B?QmVrcsOmZnQgZGluIGUtbWFpbC1hZHJlc3Nl?=",
|
||||
content: `Kære ${name},<br><br>Velkommen til vores interne password manager PasswordBox. For at fuldføre oprettelsesprocessen skal du bekræfte din e-mail-adresse ved at klikke på nedenstående link:<br><br><a href="https://passwordbox.dk/verify?token=${verificationToken}">https://passwordbox.dk/verify?token=${verificationToken}</a><br><br>Hvis du ikke vil tilmeldes vores tjeneste, kan du blot ignorere denne e-mail.<br><br>Med venlig hilsen,<br>PasswordBox<br><br><i>Denne e-mail kan ikke besvares</i>`,
|
||||
});
|
||||
} catch {
|
||||
return error("Kunne ikke sende mail!");
|
||||
} finally {
|
||||
await client.close();
|
||||
}
|
||||
return ok(undefined)
|
||||
}
|
||||
|
||||
export async function SendForgotPasswordMail(userEmail: string, name: string, verificationToken: string) {
|
||||
try {
|
||||
await client.connect({
|
||||
hostname: config.smtp_server,
|
||||
port: config.smtp_port,
|
||||
username: config.smtp_username,
|
||||
password: config.smtp_password,
|
||||
});
|
||||
|
||||
await client.send({
|
||||
from: "PasswordBox <no-reply@passwordbox.dk>",
|
||||
to: userEmail,
|
||||
subject: "PasswordBox - Glemt adgangskode",
|
||||
content: `Hej ${name},<br><br><b>Der er blevet anmodet et password reset.</b><br> Klik på følgende link for at nulstille din adgangskode:<br><br><a href="https://passwordbox.dk/verify?token=${verificationToken}">https://passwordbox.dk/verify?token=${verificationToken}</a><br><br>Hvis du ikke har glemt din adgangskode, kan du blot ignorere denne e-mail.<br><br>Med venlig hilsen,<br>PasswordBox<br><br><i>Denne e-mail kan ikke besvares</i>`,
|
||||
});
|
||||
} catch {
|
||||
return error("Kunne ikke sende mail!");
|
||||
} finally {
|
||||
await client.close();
|
||||
}
|
||||
return ok(undefined)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user