🔥 Cleaning up

This commit is contained in:
Hampus Kraft
2020-03-19 08:12:00 +01:00
parent 485ad466f3
commit 0d8a4ee9fa
18 changed files with 94 additions and 56 deletions

2
.gitignore vendored
View File

@@ -3,7 +3,7 @@ dist
*.log
hasura
config.yaml
private.pem
node_modules
yarn-error.log
package-lock.json
private.pem

View File

@@ -33,6 +33,7 @@
"helmet": "3.21.3",
"hibp": "8.0.0",
"jose": "1.25.0",
"nodemailer": "6.4.5",
"otplib": "12.0.1",
"qrcode": "1.4.4",
"tsconfig-paths": "3.9.0",
@@ -49,6 +50,7 @@
"@types/jest": "25.1.4",
"@types/jsonwebtoken": "8.3.8",
"@types/node": "13.9.1",
"@types/nodemailer": "6.4.0",
"@types/qrcode": "1.3.4",
"@types/supertest": "2.0.8",
"@types/uuid": "7.0.2",

View File

@@ -13,8 +13,7 @@ async function disable({ headers, body }: Request, res: Response): Promise<unkno
const { code } = await mfaSchema.validateAsync(body)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const decodedToken = verify(headers.authorization!)
const decodedToken = verify(headers.authorization)
const user_id = decodedToken['https://hasura.io/jwt/claims']['x-hasura-user-id']
try {

View File

@@ -13,8 +13,7 @@ async function enable({ headers, body }: Request, res: Response): Promise<unknow
const { code } = await mfaSchema.validateAsync(body)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const decodedToken = verify(headers.authorization!)
const decodedToken = verify(headers.authorization)
const user_id = decodedToken['https://hasura.io/jwt/claims']['x-hasura-user-id']
try {

View File

@@ -10,8 +10,7 @@ import { verify } from '@shared/jwt'
async function generate({ headers }: Request, res: Response): Promise<unknown> {
let image_url: string
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const decodedToken = verify(headers.authorization!)
const decodedToken = verify(headers.authorization)
const user_id = decodedToken['https://hasura.io/jwt/claims']['x-hasura-user-id']
const { OTP_ISSUER = 'HBP' } = process.env

View File

@@ -7,6 +7,7 @@ import { insertUser } from '@shared/queries'
import { pwnedPassword } from 'hibp'
import { registerSchema } from '@shared/schema'
import { request } from '@shared/request'
// import { sendEmail } from '@shared/email'
import { v4 as uuidv4 } from 'uuid'
async function register({ body }: Request, res: Response): Promise<unknown> {
@@ -30,13 +31,15 @@ async function register({ body }: Request, res: Response): Promise<unknown> {
throw Boom.badImplementation()
}
const ticket = uuidv4()
try {
await request(insertUser, {
user: {
email,
active,
ticket,
username,
ticket: uuidv4(),
user_accounts: {
data: {
email,
@@ -46,6 +49,14 @@ async function register({ body }: Request, res: Response): Promise<unknown> {
}
}
})
/*if (!active) {
await sendEmail({
to: email,
subject: 'Hello World',
text: `Ticket: ${ticket}`
})
}*/
} catch (err) {
throw Boom.badImplementation()
}

View File

@@ -7,8 +7,7 @@ import { request } from '@shared/request'
import { verify } from '@shared/jwt'
async function revoke({ headers }: Request, res: Response): Promise<unknown> {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const decodedToken = verify(headers.authorization!)
const decodedToken = verify(headers.authorization)
const user_id = decodedToken['https://hasura.io/jwt/claims']['x-hasura-user-id']
try {

View File

@@ -6,17 +6,33 @@ import { deleteUserById } from '@shared/queries'
import { request } from '@shared/request'
import { verify } from '@shared/jwt'
interface HasuraData {
delete_private_user_accounts: { affected_rows: number }
delete_private_refresh_tokens: { affected_rows: number }
delete_users: { affected_rows: number }
}
async function remove({ headers }: Request, res: Response): Promise<unknown> {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const decodedToken = verify(headers.authorization!)
let hasuraData: HasuraData
const decodedToken = verify(headers.authorization)
const user_id = decodedToken['https://hasura.io/jwt/claims']['x-hasura-user-id']
try {
await request(deleteUserById, { user_id })
hasuraData = (await request(deleteUserById, { user_id })) as HasuraData
} catch (err) {
throw Boom.badImplementation()
}
const deleteUsers = hasuraData.delete_users
const deleteAccounts = hasuraData.delete_private_user_accounts
const doesNotExist = !deleteAccounts.affected_rows || !deleteUsers.affected_rows
if (doesNotExist) {
throw Boom.unauthorized('Invalid or expired JWT token.')
}
return res.status(204).send()
}

View File

@@ -7,7 +7,7 @@ import { storagePermission } from './rules'
import { verify } from '@shared/jwt'
async function delete_file(req: Request, res: Response): Promise<unknown> {
const key = `${req.params[0]}`
const key = req.params[0]
// check storage rules if allowed to get meta info of file
const jwt_token = verify(req.headers.authorization)
@@ -25,9 +25,7 @@ async function delete_file(req: Request, res: Response): Promise<unknown> {
try {
await s3.deleteObject(params).promise()
} catch (e) {
console.error('error')
console.error({ e })
} catch (err) {
throw Boom.badImplementation()
}

View File

@@ -5,7 +5,7 @@ import { asyncWrapper } from '@shared/helpers'
import { s3 } from '@shared/s3'
async function get_file(req: Request, res: Response): Promise<void> {
const key = `${req.params[0]}`
const key = req.params[0]
const token = req.query.token
// get file info
@@ -18,11 +18,9 @@ async function get_file(req: Request, res: Response): Promise<void> {
try {
data = await s3.headObject(params).promise()
} catch (e) {
if (e) {
} catch (err) {
throw Boom.notFound()
}
}
if (!data?.Metadata) {
throw Boom.forbidden()
@@ -35,7 +33,7 @@ async function get_file(req: Request, res: Response): Promise<void> {
const stream = s3.getObject(params).createReadStream()
// forward errors
stream.on('error', function error(err) {
stream.on('error', err => {
console.error(err)
throw Boom.badImplementation()
})

View File

@@ -7,7 +7,7 @@ import { storagePermission } from './rules'
import { verify } from '@shared/jwt'
async function get_file(req: Request, res: Response): Promise<unknown> {
const key = `${req.params[0]}`
const key = req.params[0]
// check storage rules if allowed to get meta info of file
const jwt_token = verify(req.headers.authorization)
@@ -26,9 +26,7 @@ async function get_file(req: Request, res: Response): Promise<unknown> {
let data
try {
data = await s3.headObject(params).promise()
} catch (e) {
console.error('error')
console.error({ e })
} catch (err) {
throw Boom.badImplementation()
}

View File

@@ -1,34 +1,13 @@
import { Request, Response } from 'express'
import Boom from '@hapi/boom'
import { UploadedFile } from 'express-fileupload'
import { asyncWrapper } from '@shared/helpers'
import { s3 } from '@shared/s3'
import { storagePermission } from './rules'
import { v4 as uuidv4 } from 'uuid'
import { verify } from '@shared/jwt'
interface UploadedFile {
/** file name */
name: string
/** A function to move the file elsewhere on your server */
mv(path: string, callback: (err: unknown) => void): void
mv(path: string): Promise<void>
/** Encoding type of the file */
encoding: string
/** The mimetype of your file */
mimetype: string
/** A buffer representation of your file, returns empty buffer in case useTempFiles option was set to true. */
data: Buffer
/** A path to the temporary file in case useTempFiles option was set to true. */
tempFilePath: string
/** A boolean that represents if the file is over the size limit */
truncated: boolean
/** Uploaded size in bytes */
size: number
/** MD5 checksum of the uploaded file */
md5: string
}
async function upload_file(req: Request, res: Response): Promise<unknown> {
if (!req.files?.file) {
throw Boom.badRequest('No file')
@@ -65,9 +44,7 @@ async function upload_file(req: Request, res: Response): Promise<unknown> {
try {
await s3.upload(upload_params).promise()
} catch (e) {
console.log('error')
console.log({ e })
} catch (err) {
throw Boom.badImplementation()
}

30
src/shared/email.ts Normal file
View File

@@ -0,0 +1,30 @@
import nodemailer from 'nodemailer'
interface Email {
to: string
text: string
from?: string
subject: string
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export async function sendEmail(options: Email): Promise<any> {
const { to, text, from = '"noreply" <noreply@example.com>', subject } = options
const testAccount = await nodemailer.createTestAccount()
const transporter = nodemailer.createTransport({
host: 'smtp.ethereal.email',
port: 587,
secure: false,
auth: {
user: testAccount.user,
pass: testAccount.pass
}
})
const info = await transporter.sendMail({ from, to, subject, text })
console.log('Message sent: %s', info.messageId)
console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info))
}

View File

@@ -583,6 +583,13 @@
version "13.9.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.1.tgz#96f606f8cd67fb018847d9b61e93997dabdefc72"
"@types/nodemailer@6.4.0":
version "6.4.0"
resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.0.tgz#d8c039be3ed685c4719a026455555be82c124b74"
integrity sha512-KY7bFWB0MahRZvVW4CuW83qcCDny59pJJ0MQ5ifvfcjNwPlIT0vW4uARO4u1gtkYnWdhSvURegecY/tzcukJcA==
dependencies:
"@types/node" "*"
"@types/parse-json@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
@@ -3718,6 +3725,11 @@ node-pre-gyp@^0.14.0:
semver "^5.3.0"
tar "^4.4.2"
nodemailer@6.4.5:
version "6.4.5"
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.4.5.tgz#45614c6454d1a947242105eeddae03df87e29916"
integrity sha512-NH7aNVQyZLAvGr2+EOto7znvz+qJ02Cb/xpou98ApUt5tEAUSVUxhvHvgV/8I5dhjKTYqUw0nasoKzLNBJKrDQ==
nopt@^4.0.1:
version "4.0.3"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"