UNPKG

@sync-in/server

Version:

The secure, open-source platform for file storage, sharing, collaboration, and sync

238 lines (237 loc) 14.3 kB
/* * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com> * This file is part of Sync-in | The open source file sync and share solution * See the LICENSE file for licensing details */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "SyncQueries", { enumerable: true, get: function() { return SyncQueries; } }); const _common = require("@nestjs/common"); const _drizzleorm = require("drizzle-orm"); const _mysqlcore = require("drizzle-orm/mysql-core"); const _nodecrypto = /*#__PURE__*/ _interop_require_default(require("node:crypto")); const _functions = require("../../../common/functions"); const _shared = require("../../../common/shared"); const _cachedecorator = require("../../../infrastructure/cache/cache.decorator"); const _cacheservice = require("../../../infrastructure/cache/services/cache.service"); const _constants = require("../../../infrastructure/database/constants"); const _utils = require("../../../infrastructure/database/utils"); const _filesschema = require("../../files/schemas/files.schema"); const _sharesschema = require("../../shares/schemas/shares.schema"); const _spacesrootsschema = require("../../spaces/schemas/spaces-roots.schema"); const _spacesschema = require("../../spaces/schemas/spaces.schema"); const _auth = require("../constants/auth"); const _sync = require("../constants/sync"); const _syncclientsschema = require("../schemas/sync-clients.schema"); const _syncpathsschema = require("../schemas/sync-paths.schema"); function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _ts_decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function _ts_metadata(k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); } function _ts_param(paramIndex, decorator) { return function(target, key) { decorator(target, key, paramIndex); }; } let SyncQueries = class SyncQueries { async clientExistsForOwner(ownerId, clientId) { const [client] = await this.db.select({ id: _syncclientsschema.syncClients.id }).from(_syncclientsschema.syncClients).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_syncclientsschema.syncClients.ownerId, ownerId), (0, _drizzleorm.eq)(_syncclientsschema.syncClients.id, clientId))).limit(1); return !!client?.id; } async getOrCreateClient(ownerId, clientId, info, ip) { const client = await this.getClient(clientId, ownerId); if (client) { if ((0, _shared.currentTimeStamp)() < client.tokenExpiration) { return client.token; } // renew token if it has expired const token = _nodecrypto.default.randomUUID(); (0, _utils.dbCheckAffectedRows)(await this.db.update(_syncclientsschema.syncClients).set({ token: token, tokenExpiration: (0, _shared.currentTimeStamp)() + (0, _functions.convertHumanTimeToSeconds)(_auth.CLIENT_TOKEN_EXPIRATION_TIME) }).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_syncclientsschema.syncClients.ownerId, ownerId), (0, _drizzleorm.eq)(_syncclientsschema.syncClients.id, clientId))).limit(1), 1); return token; } else { // create client const token = _nodecrypto.default.randomUUID(); (0, _utils.dbCheckAffectedRows)(await this.db.insert(_syncclientsschema.syncClients).values({ id: clientId, ownerId: ownerId, token: token, tokenExpiration: (0, _shared.currentTimeStamp)() + (0, _functions.convertHumanTimeToSeconds)(_auth.CLIENT_TOKEN_EXPIRATION_TIME), info: info, currentAccess: new Date(), currentIp: ip }), 1); return token; } } async getClient(clientId, ownerId, token) { const where = [ (0, _drizzleorm.eq)(_syncclientsschema.syncClients.id, clientId), ...ownerId ? [ (0, _drizzleorm.eq)(_syncclientsschema.syncClients.ownerId, ownerId) ] : [], ...token ? [ (0, _drizzleorm.eq)(_syncclientsschema.syncClients.token, token) ] : [] ]; const [client] = await this.db.select({ id: _syncclientsschema.syncClients.id, ownerId: _syncclientsschema.syncClients.ownerId, token: _syncclientsschema.syncClients.token, tokenExpiration: _syncclientsschema.syncClients.tokenExpiration, info: (0, _drizzleorm.sql)`${_syncclientsschema.syncClients.info}`.mapWith(JSON.parse), enabled: _syncclientsschema.syncClients.enabled, currentAccess: _syncclientsschema.syncClients.currentAccess, currentIp: _syncclientsschema.syncClients.currentIp, lastAccess: _syncclientsschema.syncClients.lastAccess, lastIp: _syncclientsschema.syncClients.lastIp, createdAt: _syncclientsschema.syncClients.createdAt }).from(_syncclientsschema.syncClients).where((0, _drizzleorm.and)(...where)).limit(1); return client; } async getClients(owner) { const clientId = owner.clientId || null; return this.db.select({ id: _syncclientsschema.syncClients.id, tokenExpiration: _syncclientsschema.syncClients.tokenExpiration, info: (0, _drizzleorm.sql)`${_syncclientsschema.syncClients.info}`.mapWith(JSON.parse), enabled: _syncclientsschema.syncClients.enabled, currentAccess: _syncclientsschema.syncClients.currentAccess, currentIp: _syncclientsschema.syncClients.currentIp, lastAccess: _syncclientsschema.syncClients.lastAccess, lastIp: _syncclientsschema.syncClients.lastIp, createdAt: _syncclientsschema.syncClients.createdAt, isCurrentClient: (0, _drizzleorm.sql)`IF (${clientId} IS NOT NULL AND ${_syncclientsschema.syncClients.id} = ${clientId}, 1, 0)`.mapWith(Boolean), paths: (0, _utils.concatDistinctObjectsInArray)(_syncpathsschema.syncPaths.id, { id: _syncpathsschema.syncPaths.id, settings: (0, _drizzleorm.sql)`${_syncpathsschema.syncPaths.settings}`.mapWith(JSON.parse), createdAt: _syncpathsschema.syncPaths.createdAt }) }).from(_syncclientsschema.syncClients).leftJoin(_syncpathsschema.syncPaths, (0, _drizzleorm.eq)(_syncpathsschema.syncPaths.clientId, _syncclientsschema.syncClients.id)).where((0, _drizzleorm.eq)(_syncclientsschema.syncClients.ownerId, owner.id)).groupBy(_syncclientsschema.syncClients.id).orderBy((0, _drizzleorm.desc)(_syncclientsschema.syncClients.currentAccess)); } async deleteClient(ownerId, clientId) { (0, _utils.dbCheckAffectedRows)(await this.db.delete(_syncclientsschema.syncClients).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_syncclientsschema.syncClients.ownerId, ownerId), (0, _drizzleorm.eq)(_syncclientsschema.syncClients.id, clientId))).limit(1), 1); } async renewClientTokenAndExpiration(clientId, token, expiration) { (0, _utils.dbCheckAffectedRows)(await this.db.update(_syncclientsschema.syncClients).set({ token: token, tokenExpiration: expiration }).where((0, _drizzleorm.eq)(_syncclientsschema.syncClients.id, clientId)), 1); } async updateClientInfo(client, info, ip) { await this.db.update(_syncclientsschema.syncClients).set({ lastAccess: client.currentAccess, currentAccess: new Date(), lastIp: client.currentIp, currentIp: ip, info: info }).where((0, _drizzleorm.eq)(_syncclientsschema.syncClients.id, client.id)); } getPaths(clientId) { const shareFile = (0, _mysqlcore.alias)(_filesschema.files, 'shareFile'); const spaceRootFile = (0, _mysqlcore.alias)(_filesschema.files, 'spaceRootFile'); return this.db.select({ id: _syncpathsschema.syncPaths.id, remotePath: (0, _drizzleorm.sql)` CASE WHEN ${_syncpathsschema.syncPaths.ownerId} IS NOT NULL THEN CONCAT_WS('/', ${_sync.SYNC_REPOSITORY.PERSONAL}, ${(0, _filesschema.filePathSQL)(_filesschema.files)}) WHEN ${_syncpathsschema.syncPaths.spaceId} IS NOT NULL THEN CONCAT_WS('/', ${_sync.SYNC_REPOSITORY.SPACES}, ${_spacesschema.spaces.alias}, CASE WHEN ${_syncpathsschema.syncPaths.spaceRootId} IS NULL THEN CONCAT_WS('/', IF (${_filesschema.files.path} = '.', NULL, ${_filesschema.files.path}), ${_filesschema.files.name}) ELSE CASE WHEN ${_syncpathsschema.syncPaths.fileId} IS NULL THEN ${_spacesrootsschema.spacesRoots.alias} ELSE IF (${_spacesrootsschema.spacesRoots.externalPath} IS NOT NULL, CONCAT_WS('/', ${_spacesrootsschema.spacesRoots.alias}, IF (${_filesschema.files.path} = '.', NULL, ${_filesschema.files.path}), ${_filesschema.files.name}), CONCAT_WS('/', REGEXP_REPLACE(${_filesschema.files.path}, ${(0, _filesschema.filePathSQL)(spaceRootFile)}, ${_spacesrootsschema.spacesRoots.alias}), ${_filesschema.files.name}) ) END END ) WHEN ${_syncpathsschema.syncPaths.shareId} IS NOT NULL THEN CONCAT_WS('/', ${_sync.SYNC_REPOSITORY.SHARES}, CASE WHEN ${_syncpathsschema.syncPaths.fileId} IS NULL THEN ${_sharesschema.shares.alias} ELSE IF (${shareFile.id} IS NOT NULL, IF (${_filesschema.files.id} = ${shareFile.id}, NULL, REGEXP_REPLACE(${_filesschema.files.path}, ${(0, _filesschema.filePathSQL)(shareFile)}, ${_sharesschema.shares.alias})), CONCAT_WS('/', ${_sharesschema.shares.alias}, IF (${_filesschema.files.path} = '.', NULL, ${_filesschema.files.path})) ) END, IF (${_filesschema.files.id} = ${shareFile.id}, ${_sharesschema.shares.name}, ${_filesschema.files.name}) ) ELSE NULL END `.as('remotePath'), settings: (0, _drizzleorm.sql)`${_syncpathsschema.syncPaths.settings}`.mapWith(JSON.parse) }).from(_syncpathsschema.syncPaths).leftJoin(_filesschema.files, (0, _drizzleorm.eq)(_filesschema.files.id, _syncpathsschema.syncPaths.fileId)).leftJoin(_spacesschema.spaces, (0, _drizzleorm.eq)(_spacesschema.spaces.id, _syncpathsschema.syncPaths.spaceId)).leftJoin(_spacesrootsschema.spacesRoots, (0, _drizzleorm.eq)(_spacesrootsschema.spacesRoots.id, _syncpathsschema.syncPaths.spaceRootId)).leftJoin(spaceRootFile, (0, _drizzleorm.eq)(spaceRootFile.id, _spacesrootsschema.spacesRoots.fileId)).leftJoin(_sharesschema.shares, (0, _drizzleorm.eq)(_sharesschema.shares.id, _syncpathsschema.syncPaths.shareId)).leftJoin(shareFile, (0, _drizzleorm.eq)(shareFile.id, _sharesschema.shares.fileId)).where((0, _drizzleorm.eq)(_syncpathsschema.syncPaths.clientId, clientId)); } async getPathSettings(clientId, pathId) { const [path] = await this.db.select({ settings: (0, _drizzleorm.sql)`${_syncpathsschema.syncPaths.settings}`.mapWith(JSON.parse) }).from(_syncpathsschema.syncPaths).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_syncpathsschema.syncPaths.clientId, clientId), (0, _drizzleorm.eq)(_syncpathsschema.syncPaths.id, pathId))).limit(1); return path ? path.settings : null; } async createPath(clientId, dbProps, settings) { return (0, _utils.dbGetInsertedId)(await this.db.insert(_syncpathsschema.syncPaths).values({ clientId: clientId, settings: settings, ...dbProps })); } async deletePath(clientId, pathId) { (0, _utils.dbCheckAffectedRows)(await this.db.delete(_syncpathsschema.syncPaths).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_syncpathsschema.syncPaths.id, pathId), (0, _drizzleorm.eq)(_syncpathsschema.syncPaths.clientId, clientId))), 1); } async updatePathSettings(clientId, pathId, settings) { (0, _utils.dbCheckAffectedRows)(await this.db.update(_syncpathsschema.syncPaths).set({ settings: settings }).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_syncpathsschema.syncPaths.id, pathId), (0, _drizzleorm.eq)(_syncpathsschema.syncPaths.clientId, clientId))), 1); } clearCachePathSettings(clientId, pathId) { this.cache.del(this.cache.genSlugKey(this.constructor.name, this.getPathSettings.name, clientId, pathId)).catch((e)=>console.error(e)); } constructor(db, cache){ this.db = db; this.cache = cache; } }; _ts_decorate([ (0, _cachedecorator.CacheDecorator)(900), _ts_metadata("design:type", Function), _ts_metadata("design:paramtypes", [ String, Number ]), _ts_metadata("design:returntype", Promise) ], SyncQueries.prototype, "getPathSettings", null); SyncQueries = _ts_decorate([ (0, _common.Injectable)(), _ts_param(0, (0, _common.Inject)(_constants.DB_TOKEN_PROVIDER)), _ts_metadata("design:type", Function), _ts_metadata("design:paramtypes", [ typeof DBSchema === "undefined" ? Object : DBSchema, typeof _cacheservice.Cache === "undefined" ? Object : _cacheservice.Cache ]) ], SyncQueries); //# sourceMappingURL=sync-queries.service.js.map