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('')
- ))
-
- 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) {