🎨 added optional captcha to login route

This commit is contained in:
Flam3rboy 2021-05-01 13:54:12 +02:00
parent 5e9fb8a2a2
commit bbeab4da65
8 changed files with 64 additions and 37 deletions

View File

@ -1,6 +1,6 @@
{ {
"login": { "login": {
"INVALID_LOGIN": "Ungültige E-Mail oder Telefonnummer", "INVALID_LOGIN": "E-Mail oder Telefonnummer nicht gefunden",
"INVALID_PASSWORD": "Ungültiges Passwort" "INVALID_PASSWORD": "Ungültiges Passwort"
}, },
"register": { "register": {

View File

@ -1,6 +1,6 @@
{ {
"login": { "login": {
"INVALID_LOGIN": "Invalid E-Mail or Phone", "INVALID_LOGIN": "E-Mail or Phone not found",
"INVALID_PASSWORD": "Invalid Password" "INVALID_PASSWORD": "Invalid Password"
}, },
"register": { "register": {

View File

@ -2,7 +2,7 @@ import "missing-native-js-functions";
import fs from "fs/promises"; import fs from "fs/promises";
import { Connection } from "mongoose"; import { Connection } from "mongoose";
import { Server, ServerOptions } from "lambert-server"; import { Server, ServerOptions } from "lambert-server";
import { Authentication, GlobalRateLimit } from "./middlewares/"; import { Authentication, CORS, GlobalRateLimit } from "./middlewares/";
import Config from "./util/Config"; import Config from "./util/Config";
import { db } from "@fosscord/server-util"; import { db } from "@fosscord/server-util";
import i18next from "i18next"; import i18next from "i18next";
@ -15,8 +15,7 @@ import fetch from "node-fetch";
import mongoose from "mongoose"; import mongoose from "mongoose";
// this will return the new updated document for findOneAndUpdate // this will return the new updated document for findOneAndUpdate
mongoose.set('returnOriginal', false); // https://mongoosejs.com/docs/api/model.html#model_Model.findOneAndUpdate mongoose.set("returnOriginal", false); // https://mongoosejs.com/docs/api/model.html#model_Model.findOneAndUpdate
export interface FosscordServerOptions extends ServerOptions {} export interface FosscordServerOptions extends ServerOptions {}
@ -56,6 +55,7 @@ export class FosscordServer extends Server {
this.app.use(GlobalRateLimit); this.app.use(GlobalRateLimit);
this.app.use(Authentication); this.app.use(Authentication);
this.app.use(CORS);
this.app.use(BodyParser({ inflate: true })); this.app.use(BodyParser({ inflate: true }));
const languages = await fs.readdir(__dirname + "/../locales/"); const languages = await fs.readdir(__dirname + "/../locales/");
const namespaces = await fs.readdir(__dirname + "/../locales/en/"); const namespaces = await fs.readdir(__dirname + "/../locales/en/");

View File

@ -5,7 +5,6 @@ export * from "./schema/Channel";
export * from "./schema/Guild"; export * from "./schema/Guild";
export * from "./schema/Invite"; export * from "./schema/Invite";
export * from "./schema/Message"; export * from "./schema/Message";
export * from "./util/Captcha";
export * from "./util/Config"; export * from "./util/Config";
export * from "./util/Constants"; export * from "./util/Constants";
export * from "./util/Event"; export * from "./util/Event";

View File

@ -4,4 +4,11 @@ import { NextFunction, Request, Response } from "express";
export function CORS(req: Request, res: Response, next: NextFunction) { export function CORS(req: Request, res: Response, next: NextFunction) {
res.set("Access-Control-Allow-Origin", "*"); res.set("Access-Control-Allow-Origin", "*");
res.set(
"Content-security-policy",
"script-src 'https://hcaptcha.com, https://*.hcaptcha.com' frame-src 'https://hcaptcha.com, https://*.hcaptcha.com' style-src 'https://hcaptcha.com, https://*.hcaptcha.com' connect-src 'https://hcaptcha.com, https://*.hcaptcha.com'"
);
res.set("Access-Control-Allow-Headers", req.header("Access-Control-Request-Headers"));
next();
} }

View File

@ -20,11 +20,26 @@ router.post(
$gift_code_sku_id: String, $gift_code_sku_id: String,
}), }),
async (req: Request, res: Response) => { async (req: Request, res: Response) => {
const { login, password } = req.body; const { login, password, captcha_key } = req.body;
const email = adjustEmail(login); const email = adjustEmail(login);
const query: any[] = [{ phone: login }]; const query: any[] = [{ phone: login }];
if (email) query.push({ email }); if (email) query.push({ email });
const config = Config.get();
if (config.login.requireCaptcha && config.security.captcha.enabled) {
if (!captcha_key) {
const { sitekey, service } = config.security.captcha;
return res.status(400).json({
captcha_key: ["captcha-required"],
captcha_sitekey: sitekey,
captcha_service: service,
});
}
// TODO: check captcha
}
const user = await UserModel.findOne({ $or: query }, `user_data.hash id user_settings.locale user_settings.theme`).exec(); const user = await UserModel.findOne({ $or: query }, `user_data.hash id user_settings.locale user_settings.theme`).exec();
if (!user) { if (!user) {

View File

@ -1 +0,0 @@
export {};

View File

@ -1,6 +1,5 @@
import { Config, Snowflake } from "@fosscord/server-util"; import { Config, Snowflake } from "@fosscord/server-util";
import crypto from "crypto"; import crypto from "crypto";
import fs from "fs";
export default { export default {
init() { init() {
@ -75,10 +74,14 @@ export interface DefaultOptions {
forwadedFor: string | null; forwadedFor: string | null;
captcha: { captcha: {
enabled: boolean; enabled: boolean;
service: "recaptcha" | null; // TODO: hcaptcha, custom service: "recaptcha" | "hcaptcha" | null; // TODO: hcaptcha, custom
sitekey: string | null; sitekey: string | null;
secret: string | null;
}; };
}; };
login: {
requireCaptcha: boolean;
};
register: { register: {
email: { email: {
required: boolean; required: boolean;
@ -155,8 +158,12 @@ export const DefaultOptions: DefaultOptions = {
enabled: false, enabled: false,
service: null, service: null,
sitekey: null, sitekey: null,
secret: null,
}, },
}, },
login: {
requireCaptcha: false,
},
register: { register: {
email: { email: {
required: true, required: true,