@sync-in/server 1.9.0 → 1.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -8
- package/package.json +7 -7
- package/server/app.constants.js +3 -3
- package/server/app.constants.js.map +1 -1
- package/server/app.functions.js +42 -0
- package/server/app.functions.js.map +1 -0
- package/server/applications/files/services/files-manager.service.js +2 -2
- package/server/applications/files/services/files-manager.service.js.map +1 -1
- package/server/applications/files/services/files-tasks-manager.service.js +1 -1
- package/server/applications/files/services/files-tasks-manager.service.js.map +1 -1
- package/server/applications/files/utils/send-file.js +18 -9
- package/server/applications/files/utils/send-file.js.map +1 -1
- package/server/applications/files/utils/url-file.js +6 -6
- package/server/applications/files/utils/url-file.js.map +1 -1
- package/server/applications/links/services/links-manager.service.js +1 -1
- package/server/applications/links/services/links-manager.service.js.map +1 -1
- package/server/applications/shares/interfaces/share-props.interface.js.map +1 -1
- package/server/applications/shares/services/shares-manager.service.js +6 -4
- package/server/applications/shares/services/shares-manager.service.js.map +1 -1
- package/server/applications/spaces/services/spaces-manager.service.js +15 -12
- package/server/applications/spaces/services/spaces-manager.service.js.map +1 -1
- package/server/applications/users/services/admin-users-manager.service.js +4 -0
- package/server/applications/users/services/admin-users-manager.service.js.map +1 -1
- package/server/applications/users/users.controller.js +4 -1
- package/server/applications/users/users.controller.js.map +1 -1
- package/static/assets/pdfjs/build/pdf.mjs +35 -20
- package/static/assets/pdfjs/build/pdf.mjs.map +1 -1
- package/static/assets/pdfjs/build/pdf.sandbox.mjs +2 -2
- package/static/assets/pdfjs/build/pdf.worker.mjs +1488 -52
- package/static/assets/pdfjs/build/pdf.worker.mjs.map +1 -1
- package/static/assets/pdfjs/version +1 -1
- package/static/assets/pdfjs/web/locale/be/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/bg/viewer.ftl +4 -0
- package/static/assets/pdfjs/web/locale/bs/viewer.ftl +0 -15
- package/static/assets/pdfjs/web/locale/ca/viewer.ftl +0 -4
- package/static/assets/pdfjs/web/locale/cs/viewer.ftl +4 -14
- package/static/assets/pdfjs/web/locale/cy/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/da/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/de/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/dsb/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/el/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/en-CA/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/en-GB/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/eo/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/es-AR/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/es-CL/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/es-ES/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/es-MX/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/eu/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/fi/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/fr/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/fur/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/fy-NL/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/gn/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/he/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/hsb/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/hu/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/hy-AM/viewer.ftl +0 -15
- package/static/assets/pdfjs/web/locale/ia/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/id/viewer.ftl +0 -15
- package/static/assets/pdfjs/web/locale/is/viewer.ftl +0 -15
- package/static/assets/pdfjs/web/locale/it/viewer.ftl +2 -14
- package/static/assets/pdfjs/web/locale/ja/viewer.ftl +7 -2
- package/static/assets/pdfjs/web/locale/ka/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/kab/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/kk/viewer.ftl +3 -12
- package/static/assets/pdfjs/web/locale/ko/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/nb-NO/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/nl/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/nn-NO/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/pa-IN/viewer.ftl +4 -12
- package/static/assets/pdfjs/web/locale/pl/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/pt-BR/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/rm/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/ro/viewer.ftl +2 -14
- package/static/assets/pdfjs/web/locale/ru/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/sc/viewer.ftl +0 -1
- package/static/assets/pdfjs/web/locale/sk/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/sl/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/sq/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/sv-SE/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/tg/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/th/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/tr/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/vi/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/zh-CN/viewer.ftl +2 -12
- package/static/assets/pdfjs/web/locale/zh-TW/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/viewer.css +53 -41
- package/static/assets/pdfjs/web/viewer.html +493 -132
- package/static/assets/pdfjs/web/viewer.mjs +225 -150
- package/static/assets/pdfjs/web/viewer.mjs.map +1 -1
- package/static/{chunk-LYZGJZNP.js → chunk-25PWAXTJ.js} +1 -1
- package/static/{chunk-EKEGRXCV.js → chunk-27XEAHMV.js} +1 -1
- package/static/{chunk-YMAN4LIU.js → chunk-2CAAJBRO.js} +1 -1
- package/static/{chunk-MNNCSSHN.js → chunk-2LHHXDD5.js} +1 -1
- package/static/{chunk-YCTCESL4.js → chunk-2XY4PMI5.js} +1 -1
- package/static/{chunk-ERDZ7IVF.js → chunk-33WFRCUP.js} +1 -1
- package/static/chunk-3LVFDMTN.js +1 -0
- package/static/{chunk-4FJUCMEG.js → chunk-4DF2SQD4.js} +1 -1
- package/static/{chunk-Q556XB3S.js → chunk-4EUHBTWV.js} +1 -1
- package/static/{chunk-AADK5D2H.js → chunk-4KXJ6C4N.js} +1 -1
- package/static/{chunk-BHZEPHRI.js → chunk-4OV3SAUS.js} +1 -1
- package/static/{chunk-T74SMT7I.js → chunk-5HCVWZMA.js} +1 -1
- package/static/{chunk-ZCOWBVOT.js → chunk-5HYSNQR4.js} +1 -1
- package/static/{chunk-XOTKK2NJ.js → chunk-5NHB7SV3.js} +1 -1
- package/static/chunk-6VJI4X2A.js +1 -0
- package/static/{chunk-XCLK7NJL.js → chunk-7H5O4BLV.js} +1 -1
- package/static/{chunk-ACUF7IKP.js → chunk-7NI353LS.js} +1 -1
- package/static/{chunk-Y44XDRM5.js → chunk-A6J6SOM6.js} +1 -1
- package/static/{chunk-XOF4UW3S.js → chunk-A7DSX7VP.js} +1 -1
- package/static/chunk-A7R246NW.js +1 -0
- package/static/{chunk-EL6QL4TP.js → chunk-ASBPYTLT.js} +1 -1
- package/static/chunk-BJARRIS6.js +562 -0
- package/static/{chunk-RT3K6DZR.js → chunk-CAZSNVMS.js} +1 -1
- package/static/{chunk-EIYRBM4J.js → chunk-CURVLK7L.js} +1 -1
- package/static/{chunk-7CFSJ4BO.js → chunk-DDRGLHOP.js} +1 -1
- package/static/{chunk-2XPHUNYN.js → chunk-FLPZB3OX.js} +1 -1
- package/static/{chunk-23UUFZSR.js → chunk-FRBTL2ER.js} +1 -1
- package/static/{chunk-MRF3CNLZ.js → chunk-FXM7XXWA.js} +1 -1
- package/static/{chunk-7CKHC72R.js → chunk-GDPJRUVU.js} +1 -1
- package/static/{chunk-QMHUIHSR.js → chunk-GENTF6JM.js} +1 -1
- package/static/{chunk-XX7JXKA6.js → chunk-H4RLHI3Y.js} +1 -1
- package/static/{chunk-KNZ3AQPR.js → chunk-HE6EDXWI.js} +1 -1
- package/static/{chunk-LXQGVNU2.js → chunk-IUJ4IK26.js} +1 -1
- package/static/{chunk-MVZJSG5R.js → chunk-JEVBUJQ4.js} +1 -1
- package/static/{chunk-2FOWUJQF.js → chunk-K3MOXDU5.js} +1 -1
- package/static/{chunk-PG54TWBO.js → chunk-KBWK65KM.js} +1 -1
- package/static/{chunk-5HNQLBSW.js → chunk-L3PDWJZ3.js} +2 -2
- package/static/{chunk-KDEEERWZ.js → chunk-LBXOAKBD.js} +1 -1
- package/static/{chunk-Y5RLD72B.js → chunk-LFAQLJZK.js} +1 -1
- package/static/{chunk-M4XL3JN5.js → chunk-MBFMTBVJ.js} +1 -1
- package/static/{chunk-FTSIPHMG.js → chunk-MZBO5PAR.js} +1 -1
- package/static/{chunk-DJDRX53V.js → chunk-NFIES7BC.js} +1 -1
- package/static/{chunk-24Q7OUU2.js → chunk-NK2NMAJI.js} +1 -1
- package/static/{chunk-BYWSTP3P.js → chunk-O7UXVNR2.js} +1 -1
- package/static/{chunk-3IISSX63.js → chunk-PKU4IIIR.js} +1 -1
- package/static/{chunk-NN4ONTOT.js → chunk-QUSS6SUC.js} +1 -1
- package/static/{chunk-Y2I36A4K.js → chunk-R6VB3INJ.js} +1 -1
- package/static/{chunk-CCGGCHGN.js → chunk-RJOHDAPM.js} +1 -1
- package/static/{chunk-N3P6P6GW.js → chunk-S6YKBWJE.js} +1 -1
- package/static/{chunk-AZ5TF5Y3.js → chunk-SDR3UG2F.js} +1 -1
- package/static/{chunk-C3AAEQKW.js → chunk-TGHBDJZA.js} +1 -1
- package/static/{chunk-HNMGPG72.js → chunk-TVJQXN73.js} +1 -1
- package/static/{chunk-KHRF67SG.js → chunk-U75PLYIJ.js} +1 -1
- package/static/chunk-UUX3M6DC.js +1 -0
- package/static/{chunk-S6EVLDHA.js → chunk-VJ2HWQRJ.js} +2 -2
- package/static/{chunk-QNFNXDSX.js → chunk-VO4WVT6K.js} +1 -1
- package/static/{chunk-5XUIPWOH.js → chunk-W72JYHOH.js} +1 -1
- package/static/{chunk-OJCAIKUK.js → chunk-WJYVS27M.js} +1 -1
- package/static/{chunk-HKRGIRKB.js → chunk-XAIOGRBO.js} +1 -1
- package/static/{chunk-BQZWSZNN.js → chunk-XHQEF2IX.js} +1 -1
- package/static/{chunk-RX3YQ67K.js → chunk-XXYMVRSH.js} +1 -1
- package/static/{chunk-HHWXIK2M.js → chunk-YTBSB2GE.js} +1 -1
- package/static/{chunk-LJSVNPPQ.js → chunk-YXWF2DGF.js} +1 -1
- package/static/{chunk-JMYAD7E2.js → chunk-Z6RJZIDG.js} +1 -1
- package/static/{chunk-F7TXTNZC.js → chunk-ZC5ZDCDC.js} +1 -1
- package/static/{chunk-EDJAISWO.js → chunk-ZERBTNFW.js} +8 -8
- package/static/{chunk-MRMSMTWD.js → chunk-ZPI7RQ2S.js} +1 -1
- package/static/{chunk-NOPACN4F.js → chunk-ZRBLCAOK.js} +1 -1
- package/static/index.html +2 -2
- package/static/{main-3PLRDZTO.js → main-FE6GWZXU.js} +4 -4
- package/static/{styles-Q4OZOSSK.css → styles-S5HVK4H5.css} +1 -1
- package/static/chunk-H6WOTGQ5.js +0 -1
- package/static/chunk-HC7F57NA.js +0 -1
- package/static/chunk-IOIBQGHN.js +0 -562
- package/static/chunk-J6YSFHLZ.js +0 -1
- package/static/chunk-QVFPHTOH.js +0 -1
|
@@ -6,10 +6,18 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", {
|
|
7
7
|
value: true
|
|
8
8
|
});
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
function _export(target, all) {
|
|
10
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
_export(exports, {
|
|
16
|
+
get SendFile () {
|
|
12
17
|
return SendFile;
|
|
18
|
+
},
|
|
19
|
+
get makeContentDispositionAttachment () {
|
|
20
|
+
return makeContentDispositionAttachment;
|
|
13
21
|
}
|
|
14
22
|
});
|
|
15
23
|
const _send = require("@fastify/send");
|
|
@@ -17,6 +25,10 @@ const _common = require("@nestjs/common");
|
|
|
17
25
|
const _files = require("../constants/files");
|
|
18
26
|
const _fileerror = require("../models/file-error");
|
|
19
27
|
const _files1 = require("./files");
|
|
28
|
+
function makeContentDispositionAttachment(fileName) {
|
|
29
|
+
const downloadName = fileName.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
|
|
30
|
+
return `attachment; filename="${downloadName}";filename*=UTF-8''${fileName}`;
|
|
31
|
+
}
|
|
20
32
|
let SendFile = class SendFile {
|
|
21
33
|
async checks() {
|
|
22
34
|
if (!await (0, _files1.isPathExists)(this.filePath)) {
|
|
@@ -40,10 +52,8 @@ let SendFile = class SendFile {
|
|
|
40
52
|
if (sendResult.metadata['path'] === undefined) {
|
|
41
53
|
throw new _fileerror.FileError(_common.HttpStatus.BAD_REQUEST, 'Location not found');
|
|
42
54
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
sendResult.headers['content-disposition'] = `attachment; filename="${downloadName}";filename*=UTF-8''${this.fileName}`;
|
|
46
|
-
}
|
|
55
|
+
// Force file to be downloaded as an attachment
|
|
56
|
+
sendResult.headers['content-disposition'] = makeContentDispositionAttachment(this.fileName);
|
|
47
57
|
res.headers(sendResult.headers);
|
|
48
58
|
res.status(sendResult.statusCode);
|
|
49
59
|
// sendStream.once('stream', () => console.log(`Sending: ${this.fileName}`))
|
|
@@ -51,7 +61,7 @@ let SendFile = class SendFile {
|
|
|
51
61
|
// sendStream.once('error', (e: Error) => console.error(`Transfer error : ${this.fileName} - ${e}`))
|
|
52
62
|
return new _common.StreamableFile(sendResult.stream);
|
|
53
63
|
}
|
|
54
|
-
constructor(filePath,
|
|
64
|
+
constructor(filePath, downloadName = '', sendOptions = {
|
|
55
65
|
acceptRanges: true,
|
|
56
66
|
etag: true,
|
|
57
67
|
dotfiles: 'allow',
|
|
@@ -62,7 +72,6 @@ let SendFile = class SendFile {
|
|
|
62
72
|
highWaterMark: _files.DEFAULT_HIGH_WATER_MARK
|
|
63
73
|
}){
|
|
64
74
|
this.filePath = filePath;
|
|
65
|
-
this.asAttachment = asAttachment;
|
|
66
75
|
this.downloadName = downloadName;
|
|
67
76
|
this.sendOptions = sendOptions;
|
|
68
77
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/files/utils/send-file.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { send, SendOptions, SendResult } from '@fastify/send'\nimport { HttpStatus, StreamableFile } from '@nestjs/common'\nimport { FastifyReply, FastifyRequest } from 'fastify'\nimport { DEFAULT_HIGH_WATER_MARK } from '../constants/files'\nimport { FileError } from '../models/file-error'\nimport { fileName, isPathExists, isPathIsDir, isPathIsReadable } from './files'\n\nexport class SendFile {\n private fileName: string\n\n constructor(\n private readonly filePath: string,\n private readonly
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/files/utils/send-file.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { send, SendOptions, SendResult } from '@fastify/send'\nimport { HttpStatus, StreamableFile } from '@nestjs/common'\nimport { FastifyReply, FastifyRequest } from 'fastify'\nimport { DEFAULT_HIGH_WATER_MARK } from '../constants/files'\nimport { FileError } from '../models/file-error'\nimport { fileName, isPathExists, isPathIsDir, isPathIsReadable } from './files'\n\nexport function makeContentDispositionAttachment(fileName: string) {\n const downloadName = fileName.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '')\n return `attachment; filename=\"${downloadName}\";filename*=UTF-8''${fileName}`\n}\n\nexport class SendFile {\n private fileName: string\n\n constructor(\n private readonly filePath: string,\n private readonly downloadName = '',\n private readonly sendOptions: SendOptions = {\n acceptRanges: true,\n etag: true,\n dotfiles: 'allow',\n lastModified: true,\n cacheControl: true,\n maxAge: 0,\n index: false,\n highWaterMark: DEFAULT_HIGH_WATER_MARK\n }\n ) {}\n\n async checks() {\n if (!(await isPathExists(this.filePath))) {\n throw new FileError(HttpStatus.NOT_FOUND, 'Location not found')\n }\n if (await isPathIsDir(this.filePath)) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'The location is a directory')\n }\n if (!(await isPathIsReadable(this.filePath))) {\n throw new FileError(HttpStatus.METHOD_NOT_ALLOWED, 'The location is not readable')\n }\n }\n\n async stream(req: FastifyRequest, res: FastifyReply): Promise<StreamableFile> {\n // SendStream manages HEAD (no including body in response) & GET request (with body)\n // Ranges, LastModified, Etag are also handled\n // Send function uses decodeURIComponent, but filePath is already decoded: we need to encode it again before passing it.\n const encodedFilePath = encodeURIComponent(this.filePath)\n this.fileName = encodeURIComponent(this.downloadName ? this.downloadName : fileName(this.filePath))\n const sendResult: SendResult = await send(req.raw, encodedFilePath, this.sendOptions)\n // Check if the path was correctly validated\n if (sendResult.metadata['path'] === undefined) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'Location not found')\n }\n // Force file to be downloaded as an attachment\n sendResult.headers['content-disposition'] = makeContentDispositionAttachment(this.fileName)\n res.headers(sendResult.headers)\n res.status(sendResult.statusCode)\n // sendStream.once('stream', () => console.log(`Sending: ${this.fileName}`))\n // sendStream.once('end', () => console.log(`Received: ${this.fileName}`))\n // sendStream.once('error', (e: Error) => console.error(`Transfer error : ${this.fileName} - ${e}`))\n return new StreamableFile(sendResult.stream)\n }\n}\n"],"names":["SendFile","makeContentDispositionAttachment","fileName","downloadName","normalize","replace","checks","isPathExists","filePath","FileError","HttpStatus","NOT_FOUND","isPathIsDir","BAD_REQUEST","isPathIsReadable","METHOD_NOT_ALLOWED","stream","req","res","encodedFilePath","encodeURIComponent","sendResult","send","raw","sendOptions","metadata","undefined","headers","status","statusCode","StreamableFile","acceptRanges","etag","dotfiles","lastModified","cacheControl","maxAge","index","highWaterMark","DEFAULT_HIGH_WATER_MARK"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAcYA;eAAAA;;QALGC;eAAAA;;;sBAP8B;wBACH;uBAEH;2BACd;wBAC4C;AAE/D,SAASA,iCAAiCC,QAAgB;IAC/D,MAAMC,eAAeD,SAASE,SAAS,CAAC,OAAOC,OAAO,CAAC,oBAAoB;IAC3E,OAAO,CAAC,sBAAsB,EAAEF,aAAa,mBAAmB,EAAED,UAAU;AAC9E;AAEO,IAAA,AAAMF,WAAN,MAAMA;IAkBX,MAAMM,SAAS;QACb,IAAI,CAAE,MAAMC,IAAAA,oBAAY,EAAC,IAAI,CAACC,QAAQ,GAAI;YACxC,MAAM,IAAIC,oBAAS,CAACC,kBAAU,CAACC,SAAS,EAAE;QAC5C;QACA,IAAI,MAAMC,IAAAA,mBAAW,EAAC,IAAI,CAACJ,QAAQ,GAAG;YACpC,MAAM,IAAIC,oBAAS,CAACC,kBAAU,CAACG,WAAW,EAAE;QAC9C;QACA,IAAI,CAAE,MAAMC,IAAAA,wBAAgB,EAAC,IAAI,CAACN,QAAQ,GAAI;YAC5C,MAAM,IAAIC,oBAAS,CAACC,kBAAU,CAACK,kBAAkB,EAAE;QACrD;IACF;IAEA,MAAMC,OAAOC,GAAmB,EAAEC,GAAiB,EAA2B;QAC5E,oFAAoF;QACpF,8CAA8C;QAC9C,wHAAwH;QACxH,MAAMC,kBAAkBC,mBAAmB,IAAI,CAACZ,QAAQ;QACxD,IAAI,CAACN,QAAQ,GAAGkB,mBAAmB,IAAI,CAACjB,YAAY,GAAG,IAAI,CAACA,YAAY,GAAGD,IAAAA,gBAAQ,EAAC,IAAI,CAACM,QAAQ;QACjG,MAAMa,aAAyB,MAAMC,IAAAA,UAAI,EAACL,IAAIM,GAAG,EAAEJ,iBAAiB,IAAI,CAACK,WAAW;QACpF,4CAA4C;QAC5C,IAAIH,WAAWI,QAAQ,CAAC,OAAO,KAAKC,WAAW;YAC7C,MAAM,IAAIjB,oBAAS,CAACC,kBAAU,CAACG,WAAW,EAAE;QAC9C;QACA,+CAA+C;QAC/CQ,WAAWM,OAAO,CAAC,sBAAsB,GAAG1B,iCAAiC,IAAI,CAACC,QAAQ;QAC1FgB,IAAIS,OAAO,CAACN,WAAWM,OAAO;QAC9BT,IAAIU,MAAM,CAACP,WAAWQ,UAAU;QAChC,4EAA4E;QAC5E,0EAA0E;QAC1E,oGAAoG;QACpG,OAAO,IAAIC,sBAAc,CAACT,WAAWL,MAAM;IAC7C;IA9CA,YACE,AAAiBR,QAAgB,EACjC,AAAiBL,eAAe,EAAE,EAClC,AAAiBqB,cAA2B;QAC1CO,cAAc;QACdC,MAAM;QACNC,UAAU;QACVC,cAAc;QACdC,cAAc;QACdC,QAAQ;QACRC,OAAO;QACPC,eAAeC,8BAAuB;IACxC,CAAC,CACD;aAZiB/B,WAAAA;aACAL,eAAAA;aACAqB,cAAAA;IAUhB;AAkCL"}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>
|
|
3
|
-
* This file is part of Sync-in | The open source file sync and share solution
|
|
4
|
-
* See the LICENSE file for licensing details
|
|
5
|
-
*/ "use strict";
|
|
1
|
+
"use strict";
|
|
6
2
|
Object.defineProperty(exports, "__esModule", {
|
|
7
3
|
value: true
|
|
8
4
|
});
|
|
@@ -12,7 +8,11 @@ Object.defineProperty(exports, "regExpPrivateIP", {
|
|
|
12
8
|
return regExpPrivateIP;
|
|
13
9
|
}
|
|
14
10
|
});
|
|
15
|
-
|
|
11
|
+
/*
|
|
12
|
+
* Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>
|
|
13
|
+
* This file is part of Sync-in | The open source file sync and share solution
|
|
14
|
+
* See the LICENSE file for licensing details
|
|
15
|
+
*/ const parts = [
|
|
16
16
|
// IPv4 loopback (127.0.0.0/8)
|
|
17
17
|
'127\\.(?:\\d{1,3}\\.){2}\\d{1,3}',
|
|
18
18
|
// IPv4 link-local (169.254.0.0/16)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/files/utils/url-file.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nconst parts = [\n // IPv4 loopback (127.0.0.0/8)\n '127\\\\.(?:\\\\d{1,3}\\\\.){2}\\\\d{1,3}',\n // IPv4 link-local (169.254.0.0/16)\n '169\\\\.254\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}',\n // IPv4 Carrier-grade NAT (100.64.0.0/10)\n '100\\\\.(?:6[4-9]|[7-9]\\\\d|1[01]\\\\d|12[0-7])\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}',\n // IPv4 private (10.0.0.0/8)\n '10\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}',\n // IPv4 private (192.168.0.0/16)\n '192\\\\.168\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}',\n // IPv4 private (172.16.0.0/12)\n '172\\\\.(?:1[6-9]|2\\\\d|3[0-1])\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}',\n // IPv4 & IPv6 loopback\n '::1',\n '::',\n '0.0.0.0',\n // IPv6 Unique Local Address (fc00::/7)\n 'f[cd][0-9a-f]{2}:[0-9a-f:]+',\n // IPv6 link-local (fe80::/10)\n 'fe[89ab][0-9a-f]{2}:[0-9a-f:]+'\n]\n\nexport const regExpPrivateIP = new RegExp(`^(?:${parts.join('|')})$`, 'i')\n"],"names":["regExpPrivateIP","parts","RegExp","join"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/files/utils/url-file.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nconst parts = [\n // IPv4 loopback (127.0.0.0/8)\n '127\\\\.(?:\\\\d{1,3}\\\\.){2}\\\\d{1,3}',\n // IPv4 link-local (169.254.0.0/16)\n '169\\\\.254\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}',\n // IPv4 Carrier-grade NAT (100.64.0.0/10)\n '100\\\\.(?:6[4-9]|[7-9]\\\\d|1[01]\\\\d|12[0-7])\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}',\n // IPv4 private (10.0.0.0/8)\n '10\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}',\n // IPv4 private (192.168.0.0/16)\n '192\\\\.168\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}',\n // IPv4 private (172.16.0.0/12)\n '172\\\\.(?:1[6-9]|2\\\\d|3[0-1])\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}',\n // IPv4 & IPv6 loopback\n '::1',\n '::',\n '0.0.0.0',\n // IPv6 Unique Local Address (fc00::/7)\n 'f[cd][0-9a-f]{2}:[0-9a-f:]+',\n // IPv6 link-local (fe80::/10)\n 'fe[89ab][0-9a-f]{2}:[0-9a-f:]+'\n]\n\nexport const regExpPrivateIP = new RegExp(`^(?:${parts.join('|')})$`, 'i')\n"],"names":["regExpPrivateIP","parts","RegExp","join"],"mappings":";;;;+BA6BaA;;;eAAAA;;;AA7Bb;;;;CAIC,GAED,MAAMC,QAAQ;IACZ,8BAA8B;IAC9B;IACA,mCAAmC;IACnC;IACA,yCAAyC;IACzC;IACA,4BAA4B;IAC5B;IACA,gCAAgC;IAChC;IACA,+BAA+B;IAC/B;IACA,uBAAuB;IACvB;IACA;IACA;IACA,uCAAuC;IACvC;IACA,8BAA8B;IAC9B;CACD;AAEM,MAAMD,kBAAkB,IAAIE,OAAO,CAAC,IAAI,EAAED,MAAME,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE"}
|
|
@@ -62,7 +62,7 @@ let LinksManager = class LinksManager {
|
|
|
62
62
|
this.logger.log(`${this.linkAccess.name} - *${user.login}* (${user.id}) downloading ${spaceLink.share.name}`);
|
|
63
63
|
this.incrementLinkNbAccess(link);
|
|
64
64
|
const spaceEnv = await this.spaceEnvFromLink(user, spaceLink);
|
|
65
|
-
const sendFile = this.filesManager.sendFileFromSpace(spaceEnv,
|
|
65
|
+
const sendFile = this.filesManager.sendFileFromSpace(spaceEnv, spaceLink.share.name);
|
|
66
66
|
try {
|
|
67
67
|
await sendFile.checks();
|
|
68
68
|
return await sendFile.stream(req, res);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/links/services/links-manager.service.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpException, HttpStatus, Injectable, Logger, StreamableFile } from '@nestjs/common'\nimport { FastifyReply, FastifyRequest } from 'fastify'\nimport { LoginResponseDto } from '../../../authentication/dto/login-response.dto'\nimport { JwtIdentityPayload } from '../../../authentication/interfaces/jwt-payload.interface'\nimport { AuthManager } from '../../../authentication/services/auth-manager.service'\nimport { FilesManager } from '../../files/services/files-manager.service'\nimport { SendFile } from '../../files/utils/send-file'\nimport { SPACE_REPOSITORY } from '../../spaces/constants/spaces'\nimport { SpaceEnv } from '../../spaces/models/space-env.model'\nimport { SpacesManager } from '../../spaces/services/spaces-manager.service'\nimport { UserPasswordDto } from '../../users/dto/user-properties.dto'\nimport { UserModel } from '../../users/models/user.model'\nimport { UsersManager } from '../../users/services/users-manager.service'\nimport { getAvatarBase64 } from '../../users/utils/avatar'\nimport { LINK_ERROR } from '../constants/links'\nimport { LinkAsUser } from '../interfaces/link-guest.interface'\nimport { SpaceLink } from '../interfaces/link-space.interface'\nimport { LinksQueries } from './links-queries.service'\n\n@Injectable()\nexport class LinksManager {\n private logger = new Logger(LinksManager.name)\n\n constructor(\n private readonly authManager: AuthManager,\n private readonly usersManager: UsersManager,\n private readonly filesManager: FilesManager,\n private readonly spacesManager: SpacesManager,\n private readonly linksQueries: LinksQueries\n ) {}\n\n async linkValidation(identity: JwtIdentityPayload, uuid: string): Promise<{ ok: boolean; error: string | true; link: SpaceLink }> {\n const [_link, check, ok] = await this.linkEnv(identity, uuid)\n if (!ok) {\n this.logger.warn(`${this.linkValidation.name} - ${uuid} : ${check}`)\n }\n const spaceLink: SpaceLink = ok ? await this.linksQueries.spaceLink(uuid) : null\n if (spaceLink?.owner?.login) {\n spaceLink.owner.avatar = await getAvatarBase64(spaceLink.owner.login)\n // for security reasons\n delete spaceLink.owner.login\n }\n return { ok: ok, error: ok ? null : check, link: spaceLink }\n }\n\n async linkAccess(identity: JwtIdentityPayload, uuid: string, req: FastifyRequest, res: FastifyReply): Promise<StreamableFile | LoginResponseDto> {\n const [link, check, ok] = await this.linkEnv(identity, uuid)\n if (!ok) {\n this.logger.warn(`${this.linkAccess.name} - *${link.user.login}* (${link.user.id}) : ${check}`)\n throw new HttpException(check as string, HttpStatus.BAD_REQUEST)\n }\n const user = new UserModel(link.user)\n const spaceLink: SpaceLink = await this.linksQueries.spaceLink(uuid)\n if (!spaceLink.space && !spaceLink.share.isDir) {\n // download the file (authentication has been verified before)\n this.logger.log(`${this.linkAccess.name} - *${user.login}* (${user.id}) downloading ${spaceLink.share.name}`)\n this.incrementLinkNbAccess(link)\n const spaceEnv: SpaceEnv = await this.spaceEnvFromLink(user, spaceLink)\n const sendFile: SendFile = this.filesManager.sendFileFromSpace(spaceEnv, true, spaceLink.share.name)\n try {\n await sendFile.checks()\n return await sendFile.stream(req, res)\n } catch (e) {\n this.logger.error(`${this.linkAccess.name} - unable to send file : ${e}`)\n throw new HttpException('Unable to download file', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n } else if (link.user.id !== identity.id) {\n // authenticate user to allow access to the directory\n this.logger.log(`${this.linkAccess.name} - *${user.login}* (${user.id}) is logged`)\n this.incrementLinkNbAccess(link)\n this.usersManager.updateAccesses(user, req.ip, true).catch((e: Error) => this.logger.error(`${this.linkAccess.name} - ${e}`))\n return this.authManager.setCookies(user, res)\n }\n // already authenticated\n }\n\n async linkAuthentication(identity: JwtIdentityPayload, uuid: string, linkPasswordDto: UserPasswordDto, req: FastifyRequest, res: FastifyReply) {\n const [link, check, ok] = await this.linkEnv(identity, uuid, true)\n if (!ok) {\n this.logger.warn(`${this.linkAuthentication.name} - *${link.user.login}* (${link.user.id}) : ${check}`)\n throw new HttpException(check as string, HttpStatus.BAD_REQUEST)\n }\n const authSuccess: boolean = await this.usersManager.compareUserPassword(link.user.id, linkPasswordDto.password)\n const user = new UserModel(link.user)\n this.usersManager.updateAccesses(user, req.ip, authSuccess).catch((e: Error) => this.logger.error(`${this.linkAuthentication.name} - ${e}`))\n if (!authSuccess) {\n this.logger.warn(`${this.linkAuthentication.name} - *${user.login}* (${user.id}) : auth failed`)\n throw new HttpException(LINK_ERROR.UNAUTHORIZED, HttpStatus.FORBIDDEN)\n }\n // authenticate user to allow access\n this.logger.log(`${this.linkAuthentication.name} - *${user.login}* (${user.id}) is logged`)\n return this.authManager.setCookies(user, res)\n }\n\n private spaceEnvFromLink(user: UserModel, link: SpaceLink): Promise<SpaceEnv> {\n return this.spacesManager.spaceEnv(user, [\n link.space ? SPACE_REPOSITORY.FILES : SPACE_REPOSITORY.SHARES,\n link.space ? link.space.alias : link.share.alias\n ])\n }\n\n private async linkEnv(identity: JwtIdentityPayload, uuid: string, ignoreAuth: boolean = false): Promise<[LinkAsUser, string | true, boolean]> {\n const link: LinkAsUser = await this.linksQueries.linkFromUUID(uuid)\n const check: string | true = this.checkLink(identity, link, ignoreAuth)\n const ok: boolean = check === true\n return [link, check, ok]\n }\n\n private checkLink(identity: JwtIdentityPayload, link: LinkAsUser, ignoreAuth: boolean = false): string | true {\n if (!link) {\n return LINK_ERROR.NOT_FOUND\n }\n if (!link.user.isActive) {\n return LINK_ERROR.DISABLED\n }\n if (link.limitAccess !== 0 && link.nbAccess >= link.limitAccess) {\n return LINK_ERROR.EXCEEDED\n }\n if (link.expiresAt && new Date() >= link.expiresAt) {\n return LINK_ERROR.EXPIRED\n }\n if (!ignoreAuth && link.requireAuth && link.user.id !== identity.id) {\n return LINK_ERROR.UNAUTHORIZED\n }\n return true\n }\n\n private incrementLinkNbAccess(link: LinkAsUser) {\n this.linksQueries.incrementLinkNbAccess(link.uuid).catch((e: Error) => this.logger.error(`${this.incrementLinkNbAccess.name} - ${e}`))\n }\n}\n"],"names":["LinksManager","linkValidation","identity","uuid","_link","check","ok","linkEnv","logger","warn","name","spaceLink","linksQueries","owner","login","avatar","getAvatarBase64","error","link","linkAccess","req","res","user","id","HttpException","HttpStatus","BAD_REQUEST","UserModel","space","share","isDir","log","incrementLinkNbAccess","spaceEnv","spaceEnvFromLink","sendFile","filesManager","sendFileFromSpace","checks","stream","e","INTERNAL_SERVER_ERROR","usersManager","updateAccesses","ip","catch","authManager","setCookies","linkAuthentication","linkPasswordDto","authSuccess","compareUserPassword","password","LINK_ERROR","UNAUTHORIZED","FORBIDDEN","spacesManager","SPACE_REPOSITORY","FILES","SHARES","alias","ignoreAuth","linkFromUUID","checkLink","NOT_FOUND","isActive","DISABLED","limitAccess","nbAccess","EXCEEDED","expiresAt","Date","EXPIRED","requireAuth","Logger"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/links/services/links-manager.service.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpException, HttpStatus, Injectable, Logger, StreamableFile } from '@nestjs/common'\nimport { FastifyReply, FastifyRequest } from 'fastify'\nimport { LoginResponseDto } from '../../../authentication/dto/login-response.dto'\nimport { JwtIdentityPayload } from '../../../authentication/interfaces/jwt-payload.interface'\nimport { AuthManager } from '../../../authentication/services/auth-manager.service'\nimport { FilesManager } from '../../files/services/files-manager.service'\nimport { SendFile } from '../../files/utils/send-file'\nimport { SPACE_REPOSITORY } from '../../spaces/constants/spaces'\nimport { SpaceEnv } from '../../spaces/models/space-env.model'\nimport { SpacesManager } from '../../spaces/services/spaces-manager.service'\nimport { UserPasswordDto } from '../../users/dto/user-properties.dto'\nimport { UserModel } from '../../users/models/user.model'\nimport { UsersManager } from '../../users/services/users-manager.service'\nimport { getAvatarBase64 } from '../../users/utils/avatar'\nimport { LINK_ERROR } from '../constants/links'\nimport { LinkAsUser } from '../interfaces/link-guest.interface'\nimport { SpaceLink } from '../interfaces/link-space.interface'\nimport { LinksQueries } from './links-queries.service'\n\n@Injectable()\nexport class LinksManager {\n private logger = new Logger(LinksManager.name)\n\n constructor(\n private readonly authManager: AuthManager,\n private readonly usersManager: UsersManager,\n private readonly filesManager: FilesManager,\n private readonly spacesManager: SpacesManager,\n private readonly linksQueries: LinksQueries\n ) {}\n\n async linkValidation(identity: JwtIdentityPayload, uuid: string): Promise<{ ok: boolean; error: string | true; link: SpaceLink }> {\n const [_link, check, ok] = await this.linkEnv(identity, uuid)\n if (!ok) {\n this.logger.warn(`${this.linkValidation.name} - ${uuid} : ${check}`)\n }\n const spaceLink: SpaceLink = ok ? await this.linksQueries.spaceLink(uuid) : null\n if (spaceLink?.owner?.login) {\n spaceLink.owner.avatar = await getAvatarBase64(spaceLink.owner.login)\n // for security reasons\n delete spaceLink.owner.login\n }\n return { ok: ok, error: ok ? null : check, link: spaceLink }\n }\n\n async linkAccess(identity: JwtIdentityPayload, uuid: string, req: FastifyRequest, res: FastifyReply): Promise<StreamableFile | LoginResponseDto> {\n const [link, check, ok] = await this.linkEnv(identity, uuid)\n if (!ok) {\n this.logger.warn(`${this.linkAccess.name} - *${link.user.login}* (${link.user.id}) : ${check}`)\n throw new HttpException(check as string, HttpStatus.BAD_REQUEST)\n }\n const user = new UserModel(link.user)\n const spaceLink: SpaceLink = await this.linksQueries.spaceLink(uuid)\n if (!spaceLink.space && !spaceLink.share.isDir) {\n // download the file (authentication has been verified before)\n this.logger.log(`${this.linkAccess.name} - *${user.login}* (${user.id}) downloading ${spaceLink.share.name}`)\n this.incrementLinkNbAccess(link)\n const spaceEnv: SpaceEnv = await this.spaceEnvFromLink(user, spaceLink)\n const sendFile: SendFile = this.filesManager.sendFileFromSpace(spaceEnv, spaceLink.share.name)\n try {\n await sendFile.checks()\n return await sendFile.stream(req, res)\n } catch (e) {\n this.logger.error(`${this.linkAccess.name} - unable to send file : ${e}`)\n throw new HttpException('Unable to download file', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n } else if (link.user.id !== identity.id) {\n // authenticate user to allow access to the directory\n this.logger.log(`${this.linkAccess.name} - *${user.login}* (${user.id}) is logged`)\n this.incrementLinkNbAccess(link)\n this.usersManager.updateAccesses(user, req.ip, true).catch((e: Error) => this.logger.error(`${this.linkAccess.name} - ${e}`))\n return this.authManager.setCookies(user, res)\n }\n // already authenticated\n }\n\n async linkAuthentication(identity: JwtIdentityPayload, uuid: string, linkPasswordDto: UserPasswordDto, req: FastifyRequest, res: FastifyReply) {\n const [link, check, ok] = await this.linkEnv(identity, uuid, true)\n if (!ok) {\n this.logger.warn(`${this.linkAuthentication.name} - *${link.user.login}* (${link.user.id}) : ${check}`)\n throw new HttpException(check as string, HttpStatus.BAD_REQUEST)\n }\n const authSuccess: boolean = await this.usersManager.compareUserPassword(link.user.id, linkPasswordDto.password)\n const user = new UserModel(link.user)\n this.usersManager.updateAccesses(user, req.ip, authSuccess).catch((e: Error) => this.logger.error(`${this.linkAuthentication.name} - ${e}`))\n if (!authSuccess) {\n this.logger.warn(`${this.linkAuthentication.name} - *${user.login}* (${user.id}) : auth failed`)\n throw new HttpException(LINK_ERROR.UNAUTHORIZED, HttpStatus.FORBIDDEN)\n }\n // authenticate user to allow access\n this.logger.log(`${this.linkAuthentication.name} - *${user.login}* (${user.id}) is logged`)\n return this.authManager.setCookies(user, res)\n }\n\n private spaceEnvFromLink(user: UserModel, link: SpaceLink): Promise<SpaceEnv> {\n return this.spacesManager.spaceEnv(user, [\n link.space ? SPACE_REPOSITORY.FILES : SPACE_REPOSITORY.SHARES,\n link.space ? link.space.alias : link.share.alias\n ])\n }\n\n private async linkEnv(identity: JwtIdentityPayload, uuid: string, ignoreAuth: boolean = false): Promise<[LinkAsUser, string | true, boolean]> {\n const link: LinkAsUser = await this.linksQueries.linkFromUUID(uuid)\n const check: string | true = this.checkLink(identity, link, ignoreAuth)\n const ok: boolean = check === true\n return [link, check, ok]\n }\n\n private checkLink(identity: JwtIdentityPayload, link: LinkAsUser, ignoreAuth: boolean = false): string | true {\n if (!link) {\n return LINK_ERROR.NOT_FOUND\n }\n if (!link.user.isActive) {\n return LINK_ERROR.DISABLED\n }\n if (link.limitAccess !== 0 && link.nbAccess >= link.limitAccess) {\n return LINK_ERROR.EXCEEDED\n }\n if (link.expiresAt && new Date() >= link.expiresAt) {\n return LINK_ERROR.EXPIRED\n }\n if (!ignoreAuth && link.requireAuth && link.user.id !== identity.id) {\n return LINK_ERROR.UNAUTHORIZED\n }\n return true\n }\n\n private incrementLinkNbAccess(link: LinkAsUser) {\n this.linksQueries.incrementLinkNbAccess(link.uuid).catch((e: Error) => this.logger.error(`${this.incrementLinkNbAccess.name} - ${e}`))\n }\n}\n"],"names":["LinksManager","linkValidation","identity","uuid","_link","check","ok","linkEnv","logger","warn","name","spaceLink","linksQueries","owner","login","avatar","getAvatarBase64","error","link","linkAccess","req","res","user","id","HttpException","HttpStatus","BAD_REQUEST","UserModel","space","share","isDir","log","incrementLinkNbAccess","spaceEnv","spaceEnvFromLink","sendFile","filesManager","sendFileFromSpace","checks","stream","e","INTERNAL_SERVER_ERROR","usersManager","updateAccesses","ip","catch","authManager","setCookies","linkAuthentication","linkPasswordDto","authSuccess","compareUserPassword","password","LINK_ERROR","UNAUTHORIZED","FORBIDDEN","spacesManager","SPACE_REPOSITORY","FILES","SHARES","alias","ignoreAuth","linkFromUUID","checkLink","NOT_FOUND","isActive","DISABLED","limitAccess","nbAccess","EXCEEDED","expiresAt","Date","EXPIRED","requireAuth","Logger"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/shares/interfaces/share-props.interface.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\nimport type { FileSpace } from '../../files/interfaces/file-space.interface'\nimport type { Member } from '../../users/interfaces/member.interface'\nimport type { Share } from '../schemas/share.interface'\n\nexport class ShareProps
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/shares/interfaces/share-props.interface.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\nimport type { FileSpace } from '../../files/interfaces/file-space.interface'\nimport type { Member } from '../../users/interfaces/member.interface'\nimport type { Share } from '../schemas/share.interface'\n\nexport class ShareProps implements Pick<\n Share,\n | 'id'\n | 'ownerId'\n | 'name'\n | 'alias'\n | 'enabled'\n | 'description'\n | 'externalPath'\n | 'createdAt'\n | 'modifiedAt'\n | 'disabledAt'\n | 'storageUsage'\n | 'storageQuota'\n | 'storageIndexing'\n> {\n id: number\n ownerId: number\n alias: string\n name: string\n description: string\n enabled: boolean\n externalPath: string\n storageUsage: number\n storageQuota: number\n storageIndexing: boolean\n createdAt: Date\n modifiedAt: Date\n disabledAt: Date\n parent: Pick<Share, 'id' | 'ownerId' | 'alias' | 'name'>\n file: FileSpace\n\n // Extra properties\n members: Member[] = []\n}\n"],"names":["ShareProps","members"],"mappings":"AAAA;;;;CAIC;;;;+BAKYA;;;eAAAA;;;AAAN,IAAA,AAAMA,aAAN,MAAMA;;QAgCX,mBAAmB;aACnBC,UAAoB,EAAE;;AACxB"}
|
|
@@ -654,12 +654,14 @@ let SharesManager = class SharesManager {
|
|
|
654
654
|
storageUsage: size,
|
|
655
655
|
storageQuota: share.storageQuota
|
|
656
656
|
};
|
|
657
|
-
this.sharesQueries.cache.set(`${_cache.CACHE_QUOTA_SHARE_PREFIX}-${share.id}`, shareQuota, _cache.CACHE_QUOTA_TTL).catch((e)=>this.logger.error(`${this.updateSharesExternalPathQuota.name} - ${e}`));
|
|
657
|
+
this.sharesQueries.cache.set(`${_cache.CACHE_QUOTA_SHARE_PREFIX}-${share.id}`, shareQuota, _cache.CACHE_QUOTA_TTL).catch((e)=>this.logger.error(`${this.updateSharesExternalPathQuota.name} - share *${share.alias}* (${share.id}) : ${e}`));
|
|
658
658
|
if (share.storageUsage !== shareQuota.storageUsage) {
|
|
659
|
-
this.
|
|
660
|
-
await this.sharesQueries.updateShare(share.id, {
|
|
659
|
+
this.sharesQueries.updateShare(share.id, {
|
|
661
660
|
storageUsage: shareQuota.storageUsage
|
|
662
|
-
});
|
|
661
|
+
}).then((updated)=>updated && this.logger.log(`${this.updateSharesExternalPathQuota.name} - share *${share.alias}* (${share.id}) - storage usage updated : ${shareQuota.storageUsage}`));
|
|
662
|
+
}
|
|
663
|
+
if (shareId) {
|
|
664
|
+
return shareQuota;
|
|
663
665
|
}
|
|
664
666
|
}
|
|
665
667
|
}
|