idk
This commit is contained in:
parent
349ad6356a
commit
25606bd438
@ -6,21 +6,39 @@ import { authenticator } from 'otplib';
|
|||||||
const user = new User();
|
const user = new User();
|
||||||
|
|
||||||
const userController = new Elysia()
|
const userController = new Elysia()
|
||||||
|
.get('/', ({user}) => {
|
||||||
|
return user
|
||||||
|
})
|
||||||
.post('/login', async ({ body }) => {
|
.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)
|
.get(body.username)
|
||||||
console.log(msg)
|
console.log(msg)
|
||||||
if(msg == null) return new Response("Invalid username or password", { status: 401 })
|
if(msg == null) return new Response("Invalid username or password", { status: 401 })
|
||||||
const validPassword = await Bun.password.verify(body.password, msg.password)
|
const validPassword = await Bun.password.verify(body.password, msg.password)
|
||||||
if (!validPassword) return new Response("Invalid username or password", { status: 401 })
|
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(!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)
|
return await user.createToken(msg.id)
|
||||||
})
|
})
|
||||||
.post('/register', async({body}) => {
|
// .post('/register', async({body}) => {
|
||||||
return await Bun.password.hash(body.password);
|
// return await Bun.password.hash(body.password);
|
||||||
})
|
// })
|
||||||
.get('/otp', () => {
|
.get('/otp', () => {
|
||||||
return authenticator.generateSecret();
|
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
|
export default userController
|
||||||
|
@ -1,10 +1,48 @@
|
|||||||
import { Elysia } from 'elysia'
|
import { Elysia } from 'elysia'
|
||||||
|
import db from '../Database'
|
||||||
|
import { authenticator } from 'otplib';
|
||||||
|
|
||||||
const adminController = new Elysia()
|
const adminController = new Elysia()
|
||||||
.get('/', () => "admin endpoint")
|
.get('/', () => "admin endpoint")
|
||||||
.post('/register', async({body}) => {
|
.get('/users', () => {
|
||||||
return await Bun.password.hash(body.password);
|
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
|
export default adminController
|
Binary file not shown.
@ -1,9 +1,41 @@
|
|||||||
import {Elysia} from 'elysia'
|
import {Elysia} from 'elysia'
|
||||||
import userController from './User/Controller'
|
import userController from './User/Controller'
|
||||||
import adminController from './admin/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()
|
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('/user', (app) => app.use(userController))
|
||||||
.group('/admin', (app) => app.use(adminController))
|
.group('/admin', (app) => app.use(adminController))
|
||||||
|
.group('/password', (app) => app.use(passwordController))
|
||||||
|
.use(cors())
|
||||||
.listen(3000)
|
.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"
|
"typescript": "^5.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@elysiajs/cors": "^1.1.1",
|
||||||
"elysia": "^1.1.12",
|
"elysia": "^1.1.12",
|
||||||
"kysely": "^0.27.4",
|
"kysely": "^0.27.4",
|
||||||
"nanoid": "^5.0.7",
|
"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