Basic token verification
This commit is contained in:
parent
7138e02570
commit
ec16301ae3
|
@ -34,4 +34,4 @@ tokenAuth: none
|
||||||
# "none" will disable the browser challenge,
|
# "none" will disable the browser challenge,
|
||||||
# "obf" will sent an obfuscated function to the client,
|
# "obf" will sent an obfuscated function to the client,
|
||||||
# and "basic" will just send a simple function that expects a boolean.
|
# and "basic" will just send a simple function that expects a boolean.
|
||||||
browserChallenge: none
|
browserChallenge: basic
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { createHash, randomBytes } from "crypto";
|
import { createHash, randomBytes } from "crypto"; import env from "./env";
|
||||||
import env from "./env";
|
|
||||||
import { spoop_text } from "./helpers";
|
import { spoop_text } from "./helpers";
|
||||||
|
|
||||||
export function createID() {
|
export function createID() {
|
||||||
|
|
|
@ -3,6 +3,7 @@ import jsonwebtoken from "jsonwebtoken";
|
||||||
import env from "./env";
|
import env from "./env";
|
||||||
import { readFileSync } from "fs";
|
import { readFileSync } from "fs";
|
||||||
import { Logger } from "./Logger";
|
import { Logger } from "./Logger";
|
||||||
|
import { readUser, updateUser } from "../data/user";
|
||||||
|
|
||||||
let privkey: string;
|
let privkey: string;
|
||||||
|
|
||||||
|
@ -32,12 +33,24 @@ export function generateToken(id: string): Promise<string | undefined> | undefin
|
||||||
} else if (config.tokenAuth == "uuid") {
|
} else if (config.tokenAuth == "uuid") {
|
||||||
logger.info("Generating UUID token for user " + id + "...");
|
logger.info("Generating UUID token for user " + id + "...");
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
let token: string | undefined;
|
let token: string | undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const uuid = crypto.randomUUID();
|
const uuid = crypto.randomUUID();
|
||||||
token = `${id}.${uuid}`;
|
token = `${id}.${uuid}`;
|
||||||
|
|
||||||
|
// Save token in user data
|
||||||
|
const user = await readUser(id);
|
||||||
|
if (!user) throw new Error("User not found");
|
||||||
|
|
||||||
|
if (!user.tokens) user.tokens = "[]";
|
||||||
|
|
||||||
|
const tokens = JSON.parse(user.tokens);
|
||||||
|
tokens.push(token);
|
||||||
|
|
||||||
|
user.tokens = JSON.stringify(tokens);
|
||||||
|
await updateUser(user.id, user);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.warn("Token generation failed for user " + id);
|
logger.warn("Token generation failed for user " + id);
|
||||||
reject(err);
|
reject(err);
|
||||||
|
@ -52,8 +65,24 @@ export function generateToken(id: string): Promise<string | undefined> | undefin
|
||||||
} else return new Promise(() => undefined);
|
} else return new Promise(() => undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function verifyToken(token: string) {
|
export async function verifyToken(token: string) {
|
||||||
return jsonwebtoken.verify(token, privkey, { algorithms: ["RS256"] });
|
if (config.tokenAuth !== "none") {
|
||||||
|
// Get tokens from user data
|
||||||
|
const user = await readUser(token.split(".")[0]);
|
||||||
|
if (!user) return false;
|
||||||
|
|
||||||
|
if (!user.tokens) return false;
|
||||||
|
|
||||||
|
const tokens = JSON.parse(user.tokens);
|
||||||
|
if (!tokens) return false;
|
||||||
|
|
||||||
|
// Check if the token is in the list
|
||||||
|
for (const tok of tokens) {
|
||||||
|
if (tok === token) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function decryptJWT(token: string) {
|
export async function decryptJWT(token: string) {
|
||||||
|
|
|
@ -120,6 +120,15 @@ export class Socket extends EventEmitter {
|
||||||
this.setNoteQuota(NoteQuota.PARAMS_RIDICULOUS);
|
this.setNoteQuota(NoteQuota.PARAMS_RIDICULOUS);
|
||||||
|
|
||||||
this.bindEventListeners();
|
this.bindEventListeners();
|
||||||
|
|
||||||
|
if (config.browserChallenge == "basic") {
|
||||||
|
this.sendArray([{
|
||||||
|
m: "b",
|
||||||
|
code: `~return true;`
|
||||||
|
}]);
|
||||||
|
} else if (config.browserChallenge == "obf") {
|
||||||
|
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
import { ServerEventListener } from "../../../../util/types";
|
|
||||||
|
|
||||||
export const hi: ServerEventListener<"b"> = {
|
|
||||||
id: "b",
|
|
||||||
callback: (msg, socket) => {
|
|
||||||
// Antibot message
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Logger } from "../../../../util/Logger";
|
import { Logger } from "../../../../util/Logger";
|
||||||
import { generateToken } from "../../../../util/token";
|
import { generateToken, verifyToken } from "../../../../util/token";
|
||||||
import { ServerEventListener } from "../../../../util/types";
|
import { ClientEvents, ServerEventListener } from "../../../../util/types";
|
||||||
import { config } from "../../../usersConfig";
|
import { config } from "../../../usersConfig";
|
||||||
|
|
||||||
const logger = new Logger("Hi handler");
|
const logger = new Logger("Hi handler");
|
||||||
|
@ -9,9 +9,24 @@ export const hi: ServerEventListener<"hi"> = {
|
||||||
id: "hi",
|
id: "hi",
|
||||||
callback: async (msg, socket) => {
|
callback: async (msg, socket) => {
|
||||||
// Handshake message
|
// Handshake message
|
||||||
|
if (socket.rateLimits)
|
||||||
|
if (!socket.rateLimits.normal.hi.attempt()) return;
|
||||||
|
|
||||||
|
if (socket.gateway.hasProcessedHi) return;
|
||||||
|
|
||||||
let generatedToken: string | undefined;
|
let generatedToken: string | undefined;
|
||||||
|
|
||||||
|
// Browser challenge
|
||||||
|
if (config.browserChallenge == "basic") {
|
||||||
|
if (typeof msg.code !== "boolean") return;
|
||||||
|
|
||||||
|
if (msg.code === true) {
|
||||||
|
socket.gateway.hasCompletedBrowserChallenge = true;
|
||||||
|
}
|
||||||
|
} else if (config.browserChallenge == "obf") {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
// Is the browser challenge enabled and has the user completed it?
|
// Is the browser challenge enabled and has the user completed it?
|
||||||
if (config.browserChallenge !== "none" && !socket.gateway.hasCompletedBrowserChallenge) return;
|
if (config.browserChallenge !== "none" && !socket.gateway.hasCompletedBrowserChallenge) return;
|
||||||
|
|
||||||
|
@ -24,6 +39,7 @@ export const hi: ServerEventListener<"hi"> = {
|
||||||
// Check if they have passed the browser challenge
|
// Check if they have passed the browser challenge
|
||||||
// Send the token to the authenticator
|
// Send the token to the authenticator
|
||||||
// TODO
|
// TODO
|
||||||
|
const verified = await verifyToken(msg.token);
|
||||||
} else {
|
} else {
|
||||||
// Generate a token
|
// Generate a token
|
||||||
generatedToken = await generateToken(socket.getUserID());
|
generatedToken = await generateToken(socket.getUserID());
|
||||||
|
@ -33,10 +49,6 @@ export const hi: ServerEventListener<"hi"> = {
|
||||||
logger.debug("token:", generatedToken);
|
logger.debug("token:", generatedToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socket.rateLimits)
|
|
||||||
if (!socket.rateLimits.normal.hi.attempt()) return;
|
|
||||||
|
|
||||||
if (socket.gateway.hasProcessedHi) return;
|
|
||||||
let part = socket.getParticipant();
|
let part = socket.getParticipant();
|
||||||
|
|
||||||
if (!part) {
|
if (!part) {
|
||||||
|
@ -48,20 +60,22 @@ export const hi: ServerEventListener<"hi"> = {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.sendArray([
|
const m = {
|
||||||
{
|
m: "hi",
|
||||||
m: "hi",
|
accountInfo: undefined,
|
||||||
accountInfo: undefined,
|
permissions: undefined,
|
||||||
permissions: undefined,
|
t: Date.now(),
|
||||||
t: Date.now(),
|
u: {
|
||||||
u: {
|
_id: part._id,
|
||||||
_id: part._id,
|
color: part.color,
|
||||||
color: part.color,
|
name: part.name
|
||||||
name: part.name
|
},
|
||||||
},
|
token: generatedToken
|
||||||
token: generatedToken
|
}
|
||||||
}
|
|
||||||
]);
|
logger.debug("Hi message:", m);
|
||||||
|
|
||||||
|
socket.sendArray([m as ClientEvents["hi"]]);
|
||||||
|
|
||||||
socket.gateway.hasProcessedHi = true;
|
socket.gateway.hasProcessedHi = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue