diff --git a/packages/backend/src/CoreModule.js b/packages/backend/src/CoreModule.js index 6ae1c420..c16ef57f 100644 --- a/packages/backend/src/CoreModule.js +++ b/packages/backend/src/CoreModule.js @@ -216,6 +216,9 @@ const install = async ({ services, app }) => { const { PuterHomepageService } = require('./services/PuterHomepageService'); services.registerService('puter-homepage', PuterHomepageService); + + const { GetUserService } = require('./services/GetUserService'); + services.registerService('get-user', GetUserService); } const install_legacy = async ({ services }) => { diff --git a/packages/backend/src/helpers.js b/packages/backend/src/helpers.js index e2b80964..3ceb9efc 100644 --- a/packages/backend/src/helpers.js +++ b/packages/backend/src/helpers.js @@ -176,65 +176,8 @@ async function id2uuid(id){ * @param {string} options - `options` * @returns {Promise} */ - async function get_user(options){ - /** @type BaseDatabaseAccessService */ - const db = services.get('database').get(DB_READ, 'filesystem'); - - let user; - - const cached = options.cached ?? true; - - if ( cached && ! options.force ) { - if (options.username) user = kv.get('users:username:' + options.username); - else if (options.email) user = kv.get('users:email:' + options.email); - else if (options.uuid) user = kv.get('users:uuid:' + options.uuid); - else if (options.id) user = kv.get('users:id:' + options.id); - else if (options.referral_code) user = kv.get('users:referral_code:' + options.referral_code); - - if ( user ) return user; - } - - if ( ! options.force ) { - if(options.username) - user = await db.read("SELECT * FROM `user` WHERE `username` = ? LIMIT 1", [options.username]); - else if(options.email) - user = await db.read("SELECT * FROM `user` WHERE `email` = ? LIMIT 1", [options.email]); - else if(options.uuid) - user = await db.read("SELECT * FROM `user` WHERE `uuid` = ? LIMIT 1", [options.uuid]); - else if(options.id) - user = await db.read("SELECT * FROM `user` WHERE `id` = ? LIMIT 1", [options.id]); - else if(options.referral_code) - user = await db.read("SELECT * FROM `user` WHERE `referral_code` = ? LIMIT 1", [options.referral_code]); - } - - if(!user || !user[0]){ - if(options.username) - user = await db.pread("SELECT * FROM `user` WHERE `username` = ? LIMIT 1", [options.username]) - else if(options.email) - user = await db.pread("SELECT * FROM `user` WHERE `email` = ? LIMIT 1", [options.email]); - else if(options.uuid) - user = await db.pread("SELECT * FROM `user` WHERE `uuid` = ? LIMIT 1", [options.uuid]); - else if(options.id) - user = await db.pread("SELECT * FROM `user` WHERE `id` = ? LIMIT 1", [options.id]); - else if(options.referral_code) - user = await db.pread("SELECT * FROM `user` WHERE `referral_code` = ? LIMIT 1", [options.referral_code]); - } - - user = user ? user[0] : null; - - if ( ! user ) return user; - - try { - kv.set('users:username:' + user.username, user); - kv.set('users:email:' + user.email, user); - kv.set('users:uuid:' + user.uuid, user); - kv.set('users:id:' + user.id, user); - kv.set('users:referral_code:' + user.referral_code, user); - } catch (e) { - console.error(e); - } - - return user; +async function get_user(options) { + return await services.get('get-user').get_user(options); } /** diff --git a/packages/backend/src/services/GetUserService.js b/packages/backend/src/services/GetUserService.js new file mode 100644 index 00000000..9c3e695e --- /dev/null +++ b/packages/backend/src/services/GetUserService.js @@ -0,0 +1,89 @@ +const BaseService = require("./BaseService"); +const { DB_READ } = require("./database/consts"); + +/** + * Get user by one of a variety of identifying properties. + * + * Pass `cached: false` to options to force a database read. + * Pass `force: true` to options to force a primary database read. + * + * This provides the functionality of `get_user` (helpers.js) + * as a service so that other services can register identifying + * properties for caching. + * + * The original `get_user` function now uses this service. + */ +class GetUserService extends BaseService { + _construct () { + this.id_properties = new Set(); + + this.id_properties.add('username'); + this.id_properties.add('uuid'); + this.id_properties.add('id'); + this.id_properties.add('email'); + this.id_properties.add('referral_code'); + } + async _init () { + } + async get_user (options) { + const services = this.services; + + /** @type BaseDatabaseAccessService */ + const db = services.get('database').get(DB_READ, 'filesystem'); + + const cached = options.cached ?? true; + + if ( cached && ! options.force ) { + for ( const prop of this.id_properties ) { + if ( options.hasOwnProperty(prop) ) { + const user = kv.get(`users:${prop}:${options[prop]}`); + if ( user ) return user; + } + } + } + + let user; + + if ( ! options.force ) { + for ( const prop of this.id_properties ) { + if ( options.hasOwnProperty(prop) ) { + [user] = await db.read(`SELECT * FROM \`user\` WHERE \`${prop}\` = ? LIMIT 1`, [options[prop]]); + if ( user ) break; + } + } + } + + if ( ! user || ! user[0] ) { + for ( const prop of this.id_properties ) { + if ( options.hasOwnProperty(prop) ) { + [user] = await db.pread(`SELECT * FROM \`user\` WHERE \`${prop}\` = ? LIMIT 1`, [options[prop]]); + if ( user ) break; + } + } + } + + if ( ! user ) return null; + + try { + for ( const prop of this.id_properties ) { + if ( user[prop] ) { + kv.set(`users:${prop}:${user[prop]}`, user); + } + } + // kv.set('users:username:' + user.username, user); + // kv.set('users:email:' + user.email, user); + // kv.set('users:uuid:' + user.uuid, user); + // kv.set('users:id:' + user.id, user); + // kv.set('users:referral_code:' + user.referral_code, user); + } catch (e) { + console.error(e); + } + + return user; + } + register_id_property (prop) { + this.id_properties.add(prop); + } +} + +module.exports = { GetUserService }; \ No newline at end of file