diff --git a/src/api.ts b/src/api.ts index 55d6437..d421bab 100644 --- a/src/api.ts +++ b/src/api.ts @@ -3,8 +3,8 @@ import * as base64id from "base64id"; import { config } from "./config"; import {unlink} from "fs"; -async function register(name: string, password: string, confirm: string): Promise { - if(!config['satyr']['registration']) return {"error":"registration disabled"}; +async function register(name: string, password: string, confirm: string, invite?: boolean): Promise { + if(!config['satyr']['registration'] && !invite) return {"error":"registration disabled"}; if(name.includes(';') || name.includes(' ') || name.includes('\'')) return {"error":"illegal characters"}; if(password !== confirm) return {"error":"mismatched passwords"}; for(let i=0;i{ return invitecode; } -async function useInvite(code: string): Promise{ +async function validInvite(code: string): Promise{ if(typeof(code) !== "string" || code === "") return false; var result = await db.query('SELECT code FROM invites WHERE code='+db.raw.escape(code)); if(!result[0] || result[0]['code'] !== code) return false; - await db.query('DELETE FROM invites WHERE code='+db.raw.escape(code)); return true; } -export { register, update, changepwd, changesk, login, updateChat, deleteVODs, getConfig, genInvite, useInvite }; \ No newline at end of file +async function useInvite(code: string): Promise{ + if(validInvite(code)) await db.query('DELETE FROM invites WHERE code='+db.raw.escape(code)); +} + +export { register, update, changepwd, changesk, login, updateChat, deleteVODs, getConfig, genInvite, useInvite, validInvite }; \ No newline at end of file diff --git a/src/config.ts b/src/config.ts index 4bd6ec0..0fdeaa4 100644 --- a/src/config.ts +++ b/src/config.ts @@ -16,7 +16,7 @@ const config: Object = { domain: '', registration: false, email: null, - restrictedNames: [ 'live', 'user', 'users', 'register', 'login' ], + restrictedNames: [ 'live', 'user', 'users', 'register', 'login', 'invite' ], rootredirect: '/users/live', version: process.env.npm_package_version, }, localconfig['satyr']), diff --git a/src/http.ts b/src/http.ts index b5f9c53..4f2544d 100644 --- a/src/http.ts +++ b/src/http.ts @@ -224,6 +224,21 @@ async function initAPI() { }); }); app.post('/api/register', (req, res) => { + if("invite" in req.body){ + if(api.validInvite(req.body.invite)){ + api.register(req.body.username, req.body.password, req.body.confirm, true).then((result) => { + if(result[0]) return genToken(req.body.username).then((t) => { + res.cookie('Authorization', t, {maxAge: 604800000, httpOnly: true, sameSite: 'Lax'}); + res.json(result); + api.useInvite(req.body.invite); + return; + }); + res.json(result); + }); + } + else res.json({error: "invalid invite code"}); + } + else api.register(req.body.username, req.body.password, req.body.confirm).then( (result) => { if(result[0]) return genToken(req.body.username).then((t) => { res.cookie('Authorization', t, {maxAge: 604800000, httpOnly: true, sameSite: 'Lax'}); @@ -486,6 +501,18 @@ async function initSite(openReg) { } else res.render('login.njk',njkconf); }); + app.get('/invite/:code', (req, res) => { + if(tryDecode(req.cookies.Authorization)) { + res.redirect('/profile'); + } + else res.render('invite.njk',Object.assign({icode: req.params.code}, njkconf)); + }); + app.get('/invite', (req, res) => { + if(tryDecode(req.cookies.Authorization)) { + res.redirect('/profile'); + } + else res.render('invite.njk',Object.assign({icode: ""}, njkconf)); + }); app.get('/register', (req, res) => { if(tryDecode(req.cookies.Authorization) || !openReg) { res.redirect(njkconf.rootredirect); diff --git a/templates/invite.njk b/templates/invite.njk new file mode 100644 index 0000000..9b2b30b --- /dev/null +++ b/templates/invite.njk @@ -0,0 +1,20 @@ +{% extends "base.njk" %} +{% block content %} +

You've been invited to {{ sitename }}

Already registered? Log in here.

+ +
+ Username:

+ Password:

+ Confirm:

+ Invite Code:


+ +

+ + + {% include "tos.html" %}
+ + +{% endblock %} \ No newline at end of file