diff --git a/package-lock.json b/package-lock.json index 78a6176..226357f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -166,12 +166,6 @@ "integrity": "sha512-Ja2m6hE6Qp/yp8+AuVJI1+te89H+TARXamrKFYJAuoztxaQmxmhQ5WdfrqgPre0ZCstA/nP+NKXsGgQv1yk8Tw==", "dev": true }, - "@types/escape-html": { - "version": "0.0.20", - "resolved": "https://registry.npmjs.org/@types/escape-html/-/escape-html-0.0.20.tgz", - "integrity": "sha512-6dhZJLbA7aOwkYB2GDGdIqJ20wmHnkDzaxV9PJXe7O02I2dSFTERzRB6JrX6cWKaS+VqhhY7cQUMCbO5kloFUw==", - "dev": true - }, "@types/express": { "version": "4.17.2", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.2.tgz", @@ -5591,7 +5585,7 @@ }, "yargs": { "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "requires": { "camelcase": "1.2.1", diff --git a/package.json b/package.json index b9014a4..2dec0d2 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,6 @@ "@types/basic-auth": "^1.1.2", "@types/body-parser": "^1.17.1", "@types/email-templates": "^6.0.0", - "@types/escape-html": "0.0.20", "@types/express": "^4.17.2", "@types/http-errors": "^1.6.2", "@types/lodash": "^4.14.144", @@ -51,7 +50,6 @@ "ejs": "^2.7.1", "email-addresses": "^3.1.0", "email-templates": "^6.0.3", - "escape-html": "^1.0.3", "express": "^4.17.1", "http-errors": "^1.7.3", "iab_verifier": "^0.1.2", diff --git a/src/api/admin.ts b/src/api/admin.ts index d3140ff..3d2dfc0 100644 --- a/src/api/admin.ts +++ b/src/api/admin.ts @@ -15,14 +15,13 @@ * along with this program. If not, see . */ -import { urlencoded } from 'body-parser' -import * as escape from 'escape-html' +import { json } from 'body-parser' import { Router } from 'express' -import { BadRequest, Conflict, Forbidden } from 'http-errors' +import { BadRequest, Conflict } from 'http-errors' import { Database } from '../database' import { addPurchase } from '../function/purchase' import { getStatusMessage, setStatusMessage } from '../function/statusmessage' -import { generateAuthToken, generatePurchaseId } from '../util/token' +import { generatePurchaseId } from '../util/token' import { WebsocketApi } from '../websocket' export const createAdminRouter = ({ database, websocket }: { @@ -31,12 +30,6 @@ export const createAdminRouter = ({ database, websocket }: { }) => { const router = Router() - const serverToken = generateAuthToken() - - router.get('/', (_, res) => { - res.send('status
Status message
unlock premium') - }) - router.get('/status', (_, res) => { res.json({ websocketClients: websocket.countConnections() @@ -47,23 +40,21 @@ export const createAdminRouter = ({ database, websocket }: { try { const currentStatusMessage = await getStatusMessage({ database }) - res.send('
') + res.json({ + statusMessage: currentStatusMessage + }) } catch (ex) { next(ex) } }) - router.post('/status-message', urlencoded({ extended: false }), async (req, res, next) => { + router.post('/status-message', json(), async (req, res, next) => { try { - if (typeof req.body !== 'object' || typeof req.body.smessage !== 'string' || typeof req.body.token !== 'string') { + if (typeof req.body !== 'object' || typeof req.body.message !== 'string') { throw new BadRequest() } - if (req.body.token !== serverToken) { - throw new Forbidden() - } - - const newStatusMessage = req.body.smessage as string + const newStatusMessage = req.body.message as string await setStatusMessage({ database, newStatusMessage }) @@ -75,24 +66,16 @@ export const createAdminRouter = ({ database, websocket }: { } }) - router.get('/unlock-premium', (_, res) => ( - res.send('
mail:
Month
Year
') - )) - - router.post('/unlock-premium', urlencoded({ extended: false }), async (req, res, next) => { + router.post('/unlock-premium', json(), async (req, res, next) => { try { - if (typeof req.body !== 'object' || typeof req.body.mail !== 'string' || typeof req.body.duration !== 'string' || typeof req.body.token !== 'string') { + if (typeof req.body !== 'object' || typeof req.body.mail !== 'string' || typeof req.body.duration !== 'string') { throw new BadRequest() } - if (req.body.token !== serverToken) { - throw new Forbidden() - } - const mail: string = req.body.mail const type: string = req.body.duration - if (type !== 'month' && type !== 'year') { + if (type !== 'month' && type !== 'year' || mail === '') { throw new BadRequest() } diff --git a/src/api/index.ts b/src/api/index.ts index a934325..adec511 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,6 +1,6 @@ /* * server component for the TimeLimit App - * Copyright (C) 2019 Jonas Lochmann + * Copyright (C) 2019 - 2020 Jonas Lochmann * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -38,7 +38,7 @@ export const createApi = ({ database, websocket, connectedDevicesManager }: { app.disable('x-powered-by') - app.get('/time', (req, res) => { + app.get('/time', (_, res) => { res.json({ ms: Date.now() }) @@ -53,6 +53,18 @@ export const createApi = ({ database, websocket, connectedDevicesManager }: { app.use( '/admin', (req, res, next) => { + // required for webbrowser CORS support + res.header('Access-Control-Allow-Origin', '*') + res.header('Access-Control-Allow-Headers', 'Authorization, Content-Type, Accept') + res.header('Access-Control-Allow-Methods', 'GET, POST') + + // without it, browsers ignore the cors headers + if (req.method === 'OPTIONS') { + res.sendStatus(204) + + return + } + const user = basicAuth(req) if (adminToken !== '' && user && user.pass === adminToken) {