diff --git a/src/controller/Shard.ts b/src/controller/Shard.ts index 7fc16d1..85b3c3f 100644 --- a/src/controller/Shard.ts +++ b/src/controller/Shard.ts @@ -17,22 +17,22 @@ class Shard extends EventEmitter { // #_controller: Controller; - #_id: number; - #_filePath: string; - #_args: string[]; - #_execArgv: string[]; - #_env: { [key: string]: string }; - #_respawn: boolean; - #_serverOptions: ServerOptions; + #id: number; + #filePath: string; + #args: string[]; + #execArgv: string[]; + #env: { [key: string]: string }; + #respawn: boolean; + #serverOptions: ServerOptions; - #_ready: boolean; - #_process: ChildProcess | null; - #_fatal: boolean; + #ready: boolean; + #process: ChildProcess | null; + #fatal: boolean; - #_crashes: number[]; - #_spawnedAt: number; - #_awaitingShutdown: (() => void) | null; - #_awaitingResponse: Map void>; + #crashes: number[]; + #spawnedAt: number; + #awaitingShutdown: (() => void) | null; + #awaitingResponse: Map void>; constructor (_controller: Controller, id: number, options: ShardOptions) { @@ -41,56 +41,56 @@ class Shard extends EventEmitter // this.#_controller = controller; if (typeof id !== 'number' || isNaN(id)) throw new Error('Missing ID'); - this.#_id = id; + this.#id = id; if (!options?.path) throw new Error('Missing path to file to fork'); - this.#_filePath = options.path; - this.#_args = options.args || []; - this.#_execArgv = options.execArgv || []; - this.#_env = options.env || {}; - this.#_respawn = options.respawn || false; - this.#_serverOptions = options.serverOptions || {} as ServerOptions; - this.#_serverOptions.dir = path.resolve(options.path, '..'); + this.#filePath = options.path; + this.#args = options.args || []; + this.#execArgv = options.execArgv || []; + this.#env = options.env || {}; + this.#respawn = options.respawn || false; + this.#serverOptions = options.serverOptions || {} as ServerOptions; + this.#serverOptions.dir = path.resolve(options.path, '..'); - this.#_ready = false; - this.#_process = null; - this.#_fatal = false; + this.#ready = false; + this.#process = null; + this.#fatal = false; // Keep track of crashes for preventing crash loops - this.#_crashes = []; + this.#crashes = []; // Set in the spawn method - this.#_spawnedAt = Date.now(); // Gets re-set once actually spawned + this.#spawnedAt = Date.now(); // Gets re-set once actually spawned - this.#_awaitingShutdown = null; + this.#awaitingShutdown = null; - this.#_awaitingResponse = new Map(); + this.#awaitingResponse = new Map(); } get id () { - return this.#_id; + return this.#id; } get fatal () { - return this.#_fatal; + return this.#fatal; } get process () { - return this.#_process; + return this.#process; } get ready () { - return this.#_ready; + return this.#ready; } get spawnedAt () { - return this.#_spawnedAt; + return this.#spawnedAt; } async spawn (waitForReady = false) @@ -101,24 +101,24 @@ class Shard extends EventEmitter if (this.process) throw new Error(`[shard-${this.id}] A process for this shard already exists!`); - this.#_process = fork(this.#_filePath, this.#_args, { + this.#process = fork(this.#filePath, this.#args, { env: { - ...this.#_env, + ...this.#env, SHARD_ID: this.id.toString() }, - execArgv: this.#_execArgv + execArgv: this.#execArgv }) .on('message', this._handleMessage.bind(this)) .on('exit', this._handleExit.bind(this)) .on('disconnect', this._handleDisconnect.bind(this)); // Don't know if this is going to help, but monitoring whether this gets called whenever a process on its own closes the IPC channel - this.#_process.once('spawn', () => + this.#process.once('spawn', () => { this.emit('spawn'); - if (!this.#_process) + if (!this.#process) throw new Error('Shut up TS'); - this.#_process.send({ _start: this.#_serverOptions }); - this.#_spawnedAt = Date.now(); + this.#process.send({ _start: this.#serverOptions }); + this.#spawnedAt = Date.now(); }); if (!waitForReady) return; @@ -155,19 +155,19 @@ class Shard extends EventEmitter return new Promise((resolve) => { // Clear out all other exit listeners so they don't accidentally start the process up again - if (!this.#_process) + if (!this.#process) return resolve(); - this.#_process.removeAllListeners('exit'); + this.#process.removeAllListeners('exit'); // Set timeout for force kill const to = setTimeout(() => { - if (!this.#_process) + if (!this.#process) return resolve(); - this.#_process.kill(); + this.#process.kill(); resolve(); }, KillTO); // Gracefully handle exit - this.#_process.once('exit', (code, signal) => + this.#process.once('exit', (code, signal) => { clearTimeout(to); this._handleExit(code, signal, false); @@ -179,7 +179,7 @@ class Shard extends EventEmitter clearTimeout(to); }); - this.#_process.send({ _shutdown: true }); + this.#process.send({ _shutdown: true }); }); } this._handleExit(null, null, false); @@ -188,7 +188,7 @@ class Shard extends EventEmitter send (message: IPCMessage, expectResponse = false): Promise { - if (!this.ready || !this.#_process) + if (!this.ready || !this.#process) return Promise.reject(new Error(`[shard-${this.id}] Cannot send message to dead shard.`)); return new Promise((resolve, reject) => @@ -198,14 +198,14 @@ class Shard extends EventEmitter { message._id = Util.randomUUID(); const to = setTimeout(reject, 10_000, [ new Error('Message timeout') ]); - this.#_awaitingResponse.set(message._id, (args: IPCMessage) => + this.#awaitingResponse.set(message._id, (args: IPCMessage) => { clearTimeout(to); resolve(args); }); } - this.#_process?.send(message, err => + this.#process?.send(message, err => { if (err) return reject(err); @@ -219,10 +219,10 @@ class Shard extends EventEmitter awaitShutdown () { - this.#_respawn = false; + this.#respawn = false; return new Promise((resolve) => { - this.#_awaitingShutdown = resolve; + this.#awaitingShutdown = resolve; }); } @@ -232,7 +232,7 @@ class Shard extends EventEmitter { if (message._ready) { - this.#_ready = true; + this.#ready = true; this.emit('ready'); return; } @@ -240,27 +240,27 @@ class Shard extends EventEmitter { const TO = setTimeout(() => { - this.#_process?.kill('SIGKILL'); + this.#process?.kill('SIGKILL'); }, KillTO); - this.#_process?.once('exit', () => + this.#process?.once('exit', () => { clearTimeout(TO); }); - this.#_ready = false; + this.#ready = false; this.emit('shutdown'); return; } else if (message._fatal) { - this.#_process?.removeAllListeners(); - this.#_ready = false; - this.#_fatal = true; + this.#process?.removeAllListeners(); + this.#ready = false; + this.#fatal = true; this._handleExit(null, null, false); return this.emit('fatal', message); } else if (message._id) { - const promise = this.#_awaitingResponse.get(message._id); + const promise = this.#awaitingResponse.get(message._id); if (promise) return promise(message); } @@ -275,28 +275,28 @@ class Shard extends EventEmitter this.emit('disconnect'); } - _handleExit (code: number | null, _signal: string | null, respawn = this.#_respawn) + _handleExit (code: number | null, _signal: string | null, respawn = this.#respawn) { if (this.process) this.process.removeAllListeners(); this.emit('death'); - if (this.#_awaitingShutdown) - this.#_awaitingShutdown(); + if (this.#awaitingShutdown) + this.#awaitingShutdown(); if (code !== 0) { - this.#_crashes.push(Date.now() - this.spawnedAt); + this.#crashes.push(Date.now() - this.spawnedAt); this.emit('warn', 'Shard exited with non-zero exit code'); } - this.#_ready = false; - this.#_process = null; + this.#ready = false; + this.#process = null; - const len = this.#_crashes.length; + const len = this.#crashes.length; if (len > 2) { - const last3 = this.#_crashes.slice(len - 3); + const last3 = this.#crashes.slice(len - 3); const sum = last3.reduce((s, val) => { s += val; diff --git a/src/server/Server.ts b/src/server/Server.ts index 1c76976..9ea3a40 100644 --- a/src/server/Server.ts +++ b/src/server/Server.ts @@ -412,9 +412,9 @@ class Server extends EventEmitter try { const user = await this.users.createUser(name, pass); - process.send({ _id: msg._id, success: true }); if (admin) await user.updatePermissions({ administrator: { default: 10 } }); + process.send({ _id: msg._id, success: true }); } catch (err) { diff --git a/src/server/components/UserDatabase.ts b/src/server/components/UserDatabase.ts index 0925be1..e4d5a7d 100644 --- a/src/server/components/UserDatabase.ts +++ b/src/server/components/UserDatabase.ts @@ -399,7 +399,10 @@ class UserDatabase implements UserDatabaseInterface name }); await user.setPassword(password); - await this.#db.insertOne(this.#_userCollection, user.jsonPrivate); + const json = user.jsonPrivate as {_id?: ObjectId, id?: string}; + json._id = new ObjectId(json.id); + delete json.id; + await this.#db.insertOne(this.#_userCollection, json); // await this.updateUser(user); if (!this.#disableCache) this.#cache.set(user.id, user); @@ -411,8 +414,10 @@ class UserDatabase implements UserDatabaseInterface async createApplication (data: ApplicationData) { const app = this._createApp(data); - // await this.updateApplication(app); - await this.#db.insertOne(this.#_appCollection, app.jsonPrivate); + const json = app.jsonPrivate as {_id?: ObjectId, id?: string}; + json._id = new ObjectId(json.id); + delete json.id; + await this.#db.insertOne(this.#_appCollection, json); if (!this.#disableCache) this.#cache.set(app.id, app); this.#amount.applications++; @@ -510,11 +515,11 @@ class UserDatabase implements UserDatabaseInterface * @return {*} {Promise} * @memberof UserDatabase */ - async _updateEntity (entity: T, collection: string): Promise + async _updateEntity (entity: T, collection: string): Promise { if (!(entity instanceof Entity)) throw new Error('Cannot save a non-entity instance'); - const json = entity.json as {id?: string}; + const json = entity.jsonPrivate as { id?: string }; delete json.id; await this.#db.updateOne(collection, { _id: new ObjectId(entity.id) }, json); return entity; diff --git a/src/server/interfaces/AbstractUser.ts b/src/server/interfaces/AbstractUser.ts index ee2d764..b707645 100644 --- a/src/server/interfaces/AbstractUser.ts +++ b/src/server/interfaces/AbstractUser.ts @@ -9,9 +9,9 @@ class AbstractUser extends Entity static override ProtectedFields: string[] = [ ]; - #_icon: string | null; - #_roles: Role[]; - #_temporary: boolean; + #icon: string | null; + #roles: Role[]; + #temporary: boolean; constructor (server: Server, { icon, roles = [], ...opts }: AbstractUserData) { @@ -19,9 +19,9 @@ class AbstractUser extends Entity if (this.constructor === AbstractUser) throw new Error('This class cannot be instantiated, only derived'); - this.#_icon = icon || null; - this.#_roles = roles as Role[]; - this.#_temporary = opts.temporary || false; + this.#icon = icon || null; + this.#roles = roles as Role[]; + this.#temporary = opts.temporary || false; } @@ -32,12 +32,12 @@ class AbstractUser extends Entity get temporary () { - return this.#_temporary; + return this.#temporary; } set temporary (val: boolean) { - this.#_temporary = val; + this.#temporary = val; } fetchRateLimits () @@ -47,12 +47,12 @@ class AbstractUser extends Entity get roles () { - return this.#_roles; + return this.#roles; } setIcon (icon: string) { - this.#_icon = icon; + this.#icon = icon; } /** @@ -65,7 +65,7 @@ class AbstractUser extends Entity return { ...super.jsonPrivate, icon: this.icon, - roles: this.#_roles.map(role => role.id) + roles: this.#roles.map(role => role.id) }; } @@ -94,7 +94,7 @@ class AbstractUser extends Entity get icon () { - return this.#_icon; + return this.#icon; } } diff --git a/src/server/interfaces/Endpoint.ts b/src/server/interfaces/Endpoint.ts index 0d95f3a..04fdc16 100644 --- a/src/server/interfaces/Endpoint.ts +++ b/src/server/interfaces/Endpoint.ts @@ -12,21 +12,21 @@ type SubpathDefinition = [string, string, HandlerFunction | null, (MiddlewareDef abstract class Endpoint { - #_server: Server; - #_path: string; - #_name: string; + #server: Server; + #path: string; + #name: string; - _subpaths: SubpathDefinition; - subpaths: SubpathDefinition; + #_subpaths: SubpathDefinition; + #subpaths: SubpathDefinition; - _middleware: MiddlewareDefition; - middleware: MiddlewareDefition; + #_middleware: MiddlewareDefition; + #middleware: MiddlewareDefition; - methods: EndpointDefinition; - rateLimiter: RateLimiter; - logger: LoggerClient; + #methods: EndpointDefinition; + #rateLimiter: RateLimiter; + #logger: LoggerClient; - loadOrder: number; + #loadOrder: number; #auth: MiddlewareFunction | null; constructor (server: Server, { path, name, loadOrder = 5, auth = null }: EndpointOptions) @@ -34,45 +34,45 @@ abstract class Endpoint if (!server) Util.fatal(new Error('Missing server object in endpoint')); - this.#_server = server; + this.#server = server; if (!path) Util.fatal(new Error('Missing path in endpoint')); if (!path.startsWith('/')) path = `/${path}`; - this.#_path = path; + this.#path = path; if (name) - this.#_name = name; + this.#name = name; else - this.#_name = path; + this.#name = path; if (auth === true) this.#auth = server.auth.authenticate; else this.#auth = auth; - this.subpaths = []; + this.#subpaths = []; // Subpaths that should exist on *all* endpoints, the subpaths property can be overwritten, so storing these separately to ensure they exist - this._subpaths = [ + this.#_subpaths = [ [ 'post', '/debug', this.toggleDebug.bind(this), [ server.authenticator.createAuthoriser('developer') ]] ]; // Same as above but for inheriting intermediary endpoint classes // e.g. the API endpoint class adds a ratelimiter to this // doing like this to ensure the actual endpoint classes don't overwrite it when defining middleware - this._middleware = [ ]; - this.middleware = []; + this.#_middleware = [ ]; + this.#middleware = []; - this.methods = []; + this.#methods = []; - this.rateLimiter = server.rateLimiter; - this.logger = server.createLogger(this); + this.#rateLimiter = server.rateLimiter; + this.#logger = server.createLogger(this); // Used to sort the endpoints from smallest to highest before initialisation // Useful when needing to have certain endpoints register before or after some other endpoint // E.g. 404 pages should be initialised last by having a loadOrder of 10 - this.loadOrder = loadOrder; + this.#loadOrder = loadOrder; } @@ -80,7 +80,7 @@ abstract class Endpoint { // eslint-disable-next-line prefer-const - for (let [ method, cb, mw = [] ] of this.methods) + for (let [ method, cb, mw = [] ] of this.#methods) { if (typeof method !== 'string') throw new Error(`Invalid method parameter type in Endpoint ${this.name} major path`); @@ -92,19 +92,19 @@ abstract class Endpoint const middleware = []; if (this.#auth) middleware.push(this.#auth); - middleware.push(...this._middleware, ...this.middleware, ...mw); + middleware.push(...this.#_middleware, ...this.#middleware, ...mw); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this.server.app[method](this.path, ...middleware, cb); } - this.subpaths = [ ...this._subpaths, ...this.subpaths ]; + this.#subpaths = [ ...this.#_subpaths, ...this.#subpaths ]; // eslint-disable-next-line prefer-const - for (let [ method, sub, cb, mw = [] ] of this.subpaths) + for (let [ method, sub, cb, mw = [] ] of this.#subpaths) { if (typeof method !== 'string') throw new Error(`Invalid method parameter type in Endpoint ${this.name} subpath ${sub}`); - if (!this.middleware.length && !mw.length && !cb) + if (!this.#middleware.length && !mw.length && !cb) throw new Error('Cannot have endpoint with no handler and no middleware, expecting at least one to be defined'); if (typeof mw === 'function') mw = [ mw ]; @@ -114,7 +114,7 @@ abstract class Endpoint const middleware = []; if (this.#auth) middleware.push(this.#auth); - middleware.push(...this._middleware, ...this.middleware, ...mw); + middleware.push(...this.#_middleware, ...this.#middleware, ...mw); const args = [ this.path + sub, ...middleware ]; if (cb) @@ -136,26 +136,71 @@ abstract class Endpoint const { body } = req; if (typeof body.value !== 'string') - return void res.status(400).send(`Invalid value, must be one of ${this.logger.logLevels}`); - this.logger.info(`Setting debug mode on endpoint ${this.name} to ${body.value}`); - this.logger.setLogLevel(body.value); + return void res.status(400).send(`Invalid value, must be one of ${this.#logger.logLevels}`); + this.#logger.info(`Setting debug mode on endpoint ${this.name} to ${body.value}`); + this.#logger.setLogLevel(body.value); res.status(200).send(body.value); } + protected get logger () + { + return this.#logger; + } + + protected get rateLimiter () + { + return this.#rateLimiter; + } + + get methods () + { + return this.#methods; + } + + protected set methods (methods) + { + this.#methods = methods; + } + + protected get middleware () + { + return this.#middleware; + } + + protected set middleware (mw) + { + this.#middleware = mw; + } + + get subpaths () + { + return this.#subpaths; + } + + protected set subpaths (subs) + { + this.#subpaths = subs; + } + get server () { - return this.#_server; + return this.#server; } get path () { - return this.#_path; + return this.#path; } get name () { - return this.#_name; + return this.#name; + } + + get loadOrder () + { + return this.#loadOrder; } get resolveable () diff --git a/src/server/interfaces/Entity.ts b/src/server/interfaces/Entity.ts index 23a8afd..54f9962 100644 --- a/src/server/interfaces/Entity.ts +++ b/src/server/interfaces/Entity.ts @@ -10,16 +10,16 @@ class Entity static ProtectedFields = [ '_id' ]; - #_id: string; - #_name: string; - #_disabled: boolean; - #_permissions: Permissions; - #_cachedTimestamp: number; - #_createdTimestamp: number; - #_note: string | null; + #id: string; + #name: string; + #disabled: boolean; + #permissions: Permissions; + #cachedTimestamp: number; + #createdTimestamp: number; + #note: string | null; - _db: UserDatabaseInterface; - _server: Server; + #db: UserDatabaseInterface; + #server: Server; constructor (server: Server, { note, name, disabled, id, permissions, createdTimestamp }: EntityData) { @@ -38,18 +38,28 @@ class Entity if (!name) throw new Error('Entities require a name'); - this._server = server; - this._db = server.users; - this.#_id = id; - this.#_name = name; - this.#_disabled = disabled ?? false; - this.#_permissions = PermissionManager.merge(permissions || {}, PermissionManager.DefaultPermissions); - this.#_createdTimestamp = createdTimestamp ?? Date.now(); - this.#_cachedTimestamp = Date.now(); - this.#_note = note ?? null; + this.#server = server; + this.#db = server.users; + this.#id = id; + this.#name = name; + this.#disabled = disabled ?? false; + this.#permissions = PermissionManager.merge(permissions || {}, PermissionManager.DefaultPermissions); + this.#createdTimestamp = createdTimestamp ?? Date.now(); + this.#cachedTimestamp = Date.now(); + this.#note = note ?? null; } + protected get db () + { + return this.#db; + } + + protected get server () + { + return this.#server; + } + save () { throw new Error('Expecting this function to be implemented in an inheriting class'); @@ -63,7 +73,7 @@ class Entity updatePermissions (perms: Permissions) { PermissionManager.validatePermissions(perms); - this.#_permissions = PermissionManager.merge(this.#_permissions, perms, true); + this.#permissions = PermissionManager.merge(this.#permissions, perms, true); return this.save(); } @@ -101,52 +111,52 @@ class Entity get id () { - return this.#_id; + return this.#id; } get name () { - return this.#_name; + return this.#name; } set name (str: string) { - this.#_name = str; + this.#name = str; } get disabled () { - return this.#_disabled; + return this.#disabled; } set disabled (val: boolean) { - this.#_disabled = val; + this.#disabled = val; } get permissions () { - return Object.freeze({ ...this.#_permissions }); + return Object.freeze({ ...this.#permissions }); } get note () { - return this.#_note; + return this.#note; } get createdAt () { - return new Date(this.#_createdTimestamp); + return new Date(this.#createdTimestamp); } get createdTimestamp () { - return this.#_createdTimestamp; + return this.#createdTimestamp; } get cachedTimestamp () { - return this.#_cachedTimestamp; + return this.#cachedTimestamp; } } diff --git a/src/server/structures/Flag.ts b/src/server/structures/Flag.ts index 36c2d5b..6aa84a4 100644 --- a/src/server/structures/Flag.ts +++ b/src/server/structures/Flag.ts @@ -13,15 +13,15 @@ class Flag #manager: FlagManager; - #_id: string; - #_name: string; - #_hierarchy: string; + #id: string; + #name: string; + #hierarchy: string; - #_env: FlagEnv; - #_consumer: FlagConsumer; + #env: FlagEnv; + #consumer: FlagConsumer; - #_value: FlagType; - #_type: string; + #value: FlagType; + #type: string; constructor (manager: FlagManager, data: FlagData) { @@ -41,18 +41,18 @@ class Flag if (!('value' in data)) throw new Error('Missing value'); - this.#_id = data._id; - this.#_env = data.env; - this.#_consumer = data.consumer; - this.#_name = data.name; - this.#_value = data.value; - this.#_hierarchy = data.hierarchy || ''; - this.#_type = Flag.resolveType(data.value); + this.#id = data._id; + this.#env = data.env; + this.#consumer = data.consumer; + this.#name = data.name; + this.#value = data.value; + this.#hierarchy = data.hierarchy || ''; + this.#type = Flag.resolveType(data.value); } get () { - return this.#_value as T; + return this.#value as T; } save (): Promise @@ -62,64 +62,64 @@ class Flag get name () { - return this.#_name; + return this.#name; } set name (val) { - this.#_name = val; + this.#name = val; } get id () { - return this.#_id; + return this.#id; } get type () { - return this.#_type; + return this.#type; } get value () { - return this.#_value; + return this.#value; } set value (val) { if (typeof val !== typeof this.value) throw new Error('Value type mismatch'); - this.#_value = val; + this.#value = val; } get env () { - return this.#_env; + return this.#env; } set env (val) { - this.#_env = val; + this.#env = val; } get consumer () { - return this.#_consumer; + return this.#consumer; } set consumer (val) { - this.#_consumer = val; + this.#consumer = val; } get hierarchy () { - return this.#_hierarchy; + return this.#hierarchy; } set hierarchy (val) { - this.#_hierarchy = val; + this.#hierarchy = val; } get json (): FlagData diff --git a/src/server/structures/Role.ts b/src/server/structures/Role.ts index 51cbc23..5723845 100644 --- a/src/server/structures/Role.ts +++ b/src/server/structures/Role.ts @@ -8,45 +8,45 @@ class Role extends Entity static override ProtectedFields = [ ]; - #_rateLimits: RateLimits; - #_position: number; + #rateLimits: RateLimits; + #position: number; - #_rateLimiter: RateLimiter; + #rateLimiter: RateLimiter; constructor (server: Server, { rateLimits = {}, position, ...data }: RoleData) { super(server, data); - this.#_rateLimiter = server.rateLimiter; - this.#_rateLimits = this.#_rateLimiter.validateLimits(rateLimits, { addMissing: true, deleteInvalid: true }); + this.#rateLimiter = server.rateLimiter; + this.#rateLimits = this.#rateLimiter.validateLimits(rateLimits, { addMissing: true, deleteInvalid: true }); if (position === null) throw new Error('Must supply position'); - this.#_position = position; + this.#position = position; } override save () { - return this._db.updateRole(this); + return this.db.updateRole(this); } updateRateLimits (limits: RateLimits) { - limits = this.#_rateLimiter.validateLimits(limits); + limits = this.#rateLimiter.validateLimits(limits); const entries = Object.entries(limits); for (const [ key, val ] of entries) { - this.#_rateLimits[key] = val; + this.#rateLimits[key] = val; } return this.save(); } get rateLimits () { - return this.#_rateLimits; + return this.#rateLimits; } get position () { - return this.#_position; + return this.#position; } override get jsonPrivate () @@ -54,8 +54,8 @@ class Role extends Entity const json = super.jsonPrivate; return { ...json, - rateLimits: this.#_rateLimits, - position: this.#_position + rateLimits: this.#rateLimits, + position: this.#position }; } diff --git a/src/server/structures/User.ts b/src/server/structures/User.ts index c2bb75e..c404bcf 100644 --- a/src/server/structures/User.ts +++ b/src/server/structures/User.ts @@ -14,12 +14,12 @@ class User extends AbstractUser { #passwordHash: string | null; - #_otpSecret: string | null; - #_mfa: boolean; + #otpSecret: string | null; + #mfa: boolean; - #_displayName: string | null; - #_externalProfiles: {[key: string]: ExternalProfile}; - #_applications: string[]; + #displayName: string | null; + #externalProfiles: {[key: string]: ExternalProfile}; + #applications: string[]; constructor (server: Server, data: UserData) { @@ -28,30 +28,30 @@ class User extends AbstractUser AbstractUser.ProtectedFields.push('otpSecret', 'password'); - this.#_applications = data.applications || []; - this.#_externalProfiles = data.externalProfiles || {}; + this.#applications = data.applications || []; + this.#externalProfiles = data.externalProfiles || {}; /** @private */ this.#passwordHash = data.password || null; - this.#_otpSecret = data.otpSecret || null; - this.#_mfa = data.twoFactor || false; - this.#_displayName = data.displayName || null; + this.#otpSecret = data.otpSecret || null; + this.#mfa = data.twoFactor || false; + this.#displayName = data.displayName || null; } override save () { - return this._db.updateUser(this); + return this.db.updateUser(this); } get displayName () { - return this.#_displayName || this.username; + return this.#displayName || this.username; } set displayName (str) { - this.#_displayName = str; + this.#displayName = str; } get username () @@ -76,37 +76,37 @@ class User extends AbstractUser override get twoFactor () { - return this.#_mfa; + return this.#mfa; } override set twoFactor (val: boolean) { - this.#_mfa = val; + this.#mfa = val; } get mfa () { - return this.#_mfa; + return this.#mfa; } set mfa (val: boolean) { - this.#_mfa = val; + this.#mfa = val; } get externalProfiles () { - return Object.freeze({ ...this.#_externalProfiles }); + return Object.freeze({ ...this.#externalProfiles }); } get applications () { - return this.#_applications; + return this.#applications; } get otpSecret () { - return this.#_otpSecret; + return this.#otpSecret; } async setPassword (passwd: string, save = false) @@ -119,7 +119,7 @@ class User extends AbstractUser setOtpSecret (secret: string) { - this.#_otpSecret = secret; + this.#otpSecret = secret; } async authenticate (passwd: string) @@ -145,7 +145,7 @@ class User extends AbstractUser addExternalProfile (platform: string, profile: ExternalProfile) { profile.provider = platform; - this.#_externalProfiles[platform] = profile; + this.#externalProfiles[platform] = profile; } hasExternalProfile (name: string) @@ -160,9 +160,9 @@ class User extends AbstractUser displayName: this.displayName, externalProfiles: this.externalProfiles, password: this.#passwordHash, - otpSecret: this.#_otpSecret, + otpSecret: this.#otpSecret, twoFactor: this.twoFactor, - applications: this.#_applications, + applications: this.#applications, }; } diff --git a/src/server/structures/UserApplication.ts b/src/server/structures/UserApplication.ts index 09ccaf3..951f631 100644 --- a/src/server/structures/UserApplication.ts +++ b/src/server/structures/UserApplication.ts @@ -9,9 +9,9 @@ import { AbstractUser } from '../interfaces/index.js'; class UserApplication extends AbstractUser { - #_token: string; - #_user: string; - #_description: string | null; + #token: string; + #user: string; + #description: string | null; constructor (server: Server, options: ApplicationData) { @@ -20,35 +20,35 @@ class UserApplication extends AbstractUser if (typeof options.token !== 'string') throw new Error('Missing token for appliaction'); - this.#_token = options.token; + this.#token = options.token; if (options.ownerId instanceof ObjectId) options.ownerId = options.ownerId.toString(); if (typeof options.ownerId !== 'string') throw new Error('Missing ownerId (owner) for application'); - this.#_user = options.ownerId; - this.#_description = options.description || null; + this.#user = options.ownerId; + this.#description = options.description || null; } override save () { - return this._db.updateApplication(this); + return this.db.updateApplication(this); } get ownerId () { - return this.#_user; + return this.#user; } get description () { - return this.#_description; + return this.#description; } get token () { - return this.#_token; + return this.#token; } override get jsonPrivate () @@ -56,7 +56,7 @@ class UserApplication extends AbstractUser return { ...super.jsonPrivate, token: this.token, - ownerId: new ObjectId(this.#_user), + ownerId: new ObjectId(this.#user), description: this.description, }; }