@sync-in/server
Version:
The secure, open-source platform for file storage, sharing, collaboration, and sync
238 lines (237 loc) • 14.3 kB
JavaScript
/*
* 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