summary refs log tree commit diff
path: root/api/src/routes/auth
diff options
context:
space:
mode:
Diffstat (limited to 'api/src/routes/auth')
-rw-r--r--api/src/routes/auth/login.ts32
-rw-r--r--api/src/routes/auth/register.ts104
2 files changed, 33 insertions, 103 deletions
diff --git a/api/src/routes/auth/login.ts b/api/src/routes/auth/login.ts

index dc970e4c..7fd0f870 100644 --- a/api/src/routes/auth/login.ts +++ b/api/src/routes/auth/login.ts
@@ -2,7 +2,7 @@ import { Request, Response, Router } from "express"; import { check, FieldErrors, Length } from "../../util/instanceOf"; import bcrypt from "bcrypt"; import jwt from "jsonwebtoken"; -import { Config, UserModel } from "@fosscord/util"; +import { Config, User } from "@fosscord/util"; import { adjustEmail } from "./register"; const router: Router = Router(); @@ -21,10 +21,7 @@ router.post( async (req: Request, res: Response) => { const { login, password, captcha_key, undelete } = req.body; const email = adjustEmail(login); - const query: any[] = [{ phone: login }]; - if (email) query.push({ email }); - - console.log(req.body, email); + console.log("login", email); const config = Config.get(); @@ -41,27 +38,24 @@ router.post( // TODO: check captcha } - const user = await UserModel.findOne( - { $or: query }, - { "user_data.hash": true, id: true, disabled: true, deleted: true, "user_settings.locale": true, "user_settings.theme": true } - ) - .exec() - .catch((e) => { - console.log(e, query); - throw FieldErrors({ login: { message: req.t("auth:login.INVALID_LOGIN"), code: "INVALID_LOGIN" } }); - }); + const user = await User.findOneOrFail({ + where: [{ phone: login }, { email: login }], + select: ["data", "id", "disabled", "deleted", "settings"] + }).catch((e) => { + throw FieldErrors({ login: { message: req.t("auth:login.INVALID_LOGIN"), code: "INVALID_LOGIN" } }); + }); if (undelete) { // undelete refers to un'disable' here - if (user.disabled) await UserModel.updateOne({ id: user.id }, { disabled: false }).exec(); - if (user.deleted) await UserModel.updateOne({ id: user.id }, { deleted: false }).exec(); + if (user.disabled) await User.update({ id: user.id }, { disabled: false }); + if (user.deleted) await User.update({ id: user.id }, { deleted: false }); } else { if (user.deleted) return res.status(400).json({ message: "This account is scheduled for deletion.", code: 20011 }); if (user.disabled) return res.status(400).json({ message: req.t("auth:login.ACCOUNT_DISABLED"), code: 20013 }); } // the salt is saved in the password refer to bcrypt docs - const same_password = await bcrypt.compare(password, user.user_data.hash || ""); + const same_password = await bcrypt.compare(password, user.data.hash || ""); if (!same_password) { throw FieldErrors({ password: { message: req.t("auth:login.INVALID_PASSWORD"), code: "INVALID_PASSWORD" } }); } @@ -72,7 +66,7 @@ router.post( // Discord header is just the user id as string, which is not possible with npm-jsonwebtoken package // https://user-images.githubusercontent.com/6506416/81051916-dd8c9900-8ec2-11ea-8794-daf12d6f31f0.png - res.json({ token, user_settings: user.user_settings }); + res.json({ token, settings: user.settings }); } ); @@ -106,6 +100,6 @@ export async function generateToken(id: string) { * @returns {"captcha_key": ["captcha-required"], "captcha_sitekey": null, "captcha_service": "recaptcha"} * Sucess: - * @returns {"token": "USERTOKEN", "user_settings": {"locale": "en", "theme": "dark"}} + * @returns {"token": "USERTOKEN", "settings": {"locale": "en", "theme": "dark"}} */ diff --git a/api/src/routes/auth/register.ts b/api/src/routes/auth/register.ts
index fecde874..8bcecda1 100644 --- a/api/src/routes/auth/register.ts +++ b/api/src/routes/auth/register.ts
@@ -1,12 +1,12 @@ import { Request, Response, Router } from "express"; -import { trimSpecial, User, Snowflake, UserModel, Config } from "@fosscord/util"; +import { trimSpecial, User, Snowflake, Config, defaultSettings } from "@fosscord/util"; import bcrypt from "bcrypt"; import { check, Email, EMAIL_REGEX, FieldErrors, Length } from "../../util/instanceOf"; import "missing-native-js-functions"; import { generateToken } from "./login"; import { getIpAdress, IPAnalysis, isProxy } from "../../util/ipAddress"; import { HTTPError } from "lambert-server"; -import RateLimit from "../../middlewares/RateLimit"; +import { In } from "typeorm"; const router: Router = Router(); @@ -55,13 +55,13 @@ router.post( // TODO: check password strength // adjusted_email will be slightly modified version of the user supplied email -> e.g. protection against GMail Trick - let adjusted_email: string | null = adjustEmail(email); + let adjusted_email = adjustEmail(email); // adjusted_password will be the hash of the password - let adjusted_password: string = ""; + let adjusted_password = ""; // trim special uf8 control characters -> Backspace, Newline, ... - let adjusted_username: string = trimSpecial(username); + let adjusted_username = trimSpecial(username); // discriminator will be randomly generated let discriminator = ""; @@ -92,9 +92,7 @@ router.post( if (!adjusted_email) throw FieldErrors({ email: { code: "INVALID_EMAIL", message: req.t("auth:register.INVALID_EMAIL") } }); // check if there is already an account with this email - const exists = await UserModel.findOne({ email: adjusted_email }) - .exec() - .catch((e) => {}); + const exists = await User.findOneOrFail({ email: adjusted_email }).catch((e) => {}); if (exists) { throw FieldErrors({ @@ -131,9 +129,7 @@ router.post( if (!register.allowMultipleAccounts) { // TODO: check if fingerprint was eligible generated - const exists = await UserModel.findOne({ fingerprints: fingerprint }) - .exec() - .catch((e) => {}); + const exists = await User.findOne({ where: { fingerprints: In(fingerprint) } }); if (exists) { throw FieldErrors({ @@ -168,12 +164,8 @@ router.post( // TODO: is there any better way to generate a random discriminator only once, without checking if it already exists in the mongodb database? for (let tries = 0; tries < 5; tries++) { discriminator = Math.randomIntBetween(1, 9999).toString().padStart(4, "0"); - try { - exists = await UserModel.findOne({ discriminator, username: adjusted_username }, "id").exec(); - } catch (error) { - // doesn't exist -> break - break; - } + exists = await User.findOne({ where: { discriminator, username: adjusted_username }, select: ["id"] }); + if (!exists) break; } if (exists) { @@ -189,96 +181,40 @@ router.post( // appearently discord doesn't save the date of birth and just calculate if nsfw is allowed // if nsfw_allowed is null/undefined it'll require date_of_birth to set it to true/false - const user: User = { - id: Snowflake.generate(), + const user = { created_at: new Date(), username: adjusted_username, discriminator, - avatar: null, - accent_color: null, - banner: null, + id: Snowflake.generate(), bot: false, system: false, desktop: false, mobile: false, premium: true, premium_type: 2, - phone: null, bio: "", mfa_enabled: false, verified: false, disabled: false, deleted: false, - presence: { - activities: [], - client_status: { - desktop: undefined, - mobile: undefined, - web: undefined - }, - status: "offline" - }, email: adjusted_email, nsfw_allowed: true, // TODO: depending on age - public_flags: 0n, - flags: 0n, // TODO: generate default flags - guilds: [], - user_data: { + public_flags: "0", + flags: "0", // TODO: generate + data: { hash: adjusted_password, - valid_tokens_since: new Date(), - relationships: [], - connected_accounts: [], - fingerprints: [] + valid_tokens_since: new Date() }, - user_settings: { - afk_timeout: 300, - allow_accessibility_detection: true, - animate_emoji: true, - animate_stickers: 0, - contact_sync_enabled: false, - convert_emoticons: false, - custom_status: { - emoji_id: null, - emoji_name: null, - expires_at: null, - text: null - }, - default_guilds_restricted: false, - detect_platform_accounts: true, - developer_mode: false, - disable_games_tab: false, - enable_tts_command: true, - explicit_content_filter: 0, - friend_source_flags: { all: true }, - gateway_connected: false, - gif_auto_play: true, - guild_folders: [], - guild_positions: [], - inline_attachment_media: true, - inline_embed_media: true, - locale: req.language, - message_display_compact: false, - native_phone_integration_enabled: true, - render_embeds: true, - render_reactions: true, - restricted_guilds: [], - show_current_game: true, - status: "offline", - stream_notifications_enabled: true, - theme: "dark", - timezone_offset: 0 - // timezone_offset: // TODO: timezone from request - } + settings: defaultSettings, + fingerprints: [] }; - - // insert user into database - await new UserModel(user).save(); + await User.insert(user); return res.json({ token: await generateToken(user.id) }); } ); -export function adjustEmail(email: string): string | null { +export function adjustEmail(email: string): string | undefined { // body parser already checked if it is a valid email const parts = <RegExpMatchArray>email.match(EMAIL_REGEX); // @ts-ignore @@ -304,6 +240,6 @@ export default router; * Field Error * @returns { "code": 50035, "errors": { "consent": { "_errors": [{ "code": "CONSENT_REQUIRED", "message": "You must agree to Discord's Terms of Service and Privacy Policy." }]}}, "message": "Invalid Form Body"} * - * Success 201: + * Success 200: * @returns {token: "OMITTED"} */