@sync-in/server 1.4.0 → 1.5.1
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 +26 -0
- package/README.md +2 -1
- package/package.json +5 -5
- package/server/applications/comments/comments.controller.spec.js +103 -4
- package/server/applications/comments/comments.controller.spec.js.map +1 -1
- package/server/applications/comments/services/comments-manager.service.spec.js +409 -9
- package/server/applications/comments/services/comments-manager.service.spec.js.map +1 -1
- package/server/applications/files/adapters/files-indexer-mysql.service.spec.js +333 -0
- package/server/applications/files/adapters/files-indexer-mysql.service.spec.js.map +1 -0
- package/server/applications/files/constants/routes.js +6 -1
- package/server/applications/files/constants/routes.js.map +1 -1
- package/server/applications/files/files-only-office.controller.js +11 -0
- package/server/applications/files/files-only-office.controller.js.map +1 -1
- package/server/applications/files/files-only-office.controller.spec.js +97 -3
- package/server/applications/files/files-only-office.controller.spec.js.map +1 -1
- package/server/applications/files/files-tasks.controller.spec.js +91 -1
- package/server/applications/files/files-tasks.controller.spec.js.map +1 -1
- package/server/applications/files/files.controller.spec.js +268 -46
- package/server/applications/files/files.controller.spec.js.map +1 -1
- package/server/applications/files/guards/files-only-office.guard.spec.js +77 -1
- package/server/applications/files/guards/files-only-office.guard.spec.js.map +1 -1
- package/server/applications/files/services/files-only-office-manager.service.js +5 -0
- package/server/applications/files/services/files-only-office-manager.service.js.map +1 -1
- package/server/applications/links/links.controller.spec.js +91 -58
- package/server/applications/links/links.controller.spec.js.map +1 -1
- package/server/applications/links/services/links-manager.service.js +4 -6
- package/server/applications/links/services/links-manager.service.js.map +1 -1
- package/server/applications/links/services/links-manager.service.spec.js +378 -14
- package/server/applications/links/services/links-manager.service.spec.js.map +1 -1
- package/server/applications/links/services/links-queries.service.js +1 -1
- package/server/applications/links/services/links-queries.service.js.map +1 -1
- package/server/applications/notifications/notifications.controller.spec.js +56 -1
- package/server/applications/notifications/notifications.controller.spec.js.map +1 -1
- package/server/applications/notifications/services/notifications-manager.service.spec.js +461 -5
- package/server/applications/notifications/services/notifications-manager.service.spec.js.map +1 -1
- package/server/applications/shares/services/shares-manager.service.spec.js +590 -14
- package/server/applications/shares/services/shares-manager.service.spec.js.map +1 -1
- package/server/applications/sync/interceptors/sync-diff-gzip-body.interceptor.spec.js +120 -0
- package/server/applications/sync/interceptors/sync-diff-gzip-body.interceptor.spec.js.map +1 -0
- package/server/applications/sync/services/sync-clients-manager.service.spec.js +548 -8
- package/server/applications/sync/services/sync-clients-manager.service.spec.js.map +1 -1
- package/server/applications/sync/services/sync-manager.service.spec.js +837 -5
- package/server/applications/sync/services/sync-manager.service.spec.js.map +1 -1
- package/server/applications/sync/services/sync-paths-manager.service.spec.js +900 -7
- package/server/applications/sync/services/sync-paths-manager.service.spec.js.map +1 -1
- package/server/applications/users/services/admin-users-manager.service.js +22 -24
- package/server/applications/users/services/admin-users-manager.service.js.map +1 -1
- package/server/applications/users/services/admin-users-manager.service.spec.js +763 -17
- package/server/applications/users/services/admin-users-manager.service.spec.js.map +1 -1
- package/server/applications/users/services/users-manager.service.js +1 -1
- package/server/applications/users/services/users-manager.service.js.map +1 -1
- package/server/applications/users/services/users-manager.service.spec.js +938 -49
- package/server/applications/users/services/users-manager.service.spec.js.map +1 -1
- package/server/applications/webdav/decorators/if-header.decorator.js +4 -1
- package/server/applications/webdav/decorators/if-header.decorator.js.map +1 -1
- package/server/applications/webdav/filters/webdav.filter.spec.js +77 -0
- package/server/applications/webdav/filters/webdav.filter.spec.js.map +1 -0
- package/server/applications/webdav/guards/webdav-protocol.guard.js +3 -7
- package/server/applications/webdav/guards/webdav-protocol.guard.js.map +1 -1
- package/server/applications/webdav/guards/webdav-protocol.guard.spec.js +580 -0
- package/server/applications/webdav/guards/webdav-protocol.guard.spec.js.map +1 -0
- package/server/applications/webdav/services/webdav-methods.service.spec.js +1582 -3
- package/server/applications/webdav/services/webdav-methods.service.spec.js.map +1 -1
- package/server/applications/webdav/services/webdav-spaces.service.spec.js +390 -2
- package/server/applications/webdav/services/webdav-spaces.service.spec.js.map +1 -1
- package/server/applications/webdav/webdav.controller.js +2 -2
- package/server/applications/webdav/webdav.controller.js.map +1 -1
- package/server/authentication/guards/auth-basic.guard.js.map +1 -1
- package/server/authentication/guards/auth-digest.guard.js +1 -2
- package/server/authentication/guards/auth-digest.guard.js.map +1 -1
- package/server/authentication/guards/auth-local.guard.js.map +1 -1
- package/server/infrastructure/context/interceptors/context.interceptor.spec.js +135 -0
- package/server/infrastructure/context/interceptors/context.interceptor.spec.js.map +1 -0
- package/static/3rdpartylicenses.txt +26 -26
- package/static/assets/pdfjs/build/pdf.mjs +1177 -255
- package/static/assets/pdfjs/build/pdf.mjs.map +1 -1
- package/static/assets/pdfjs/build/pdf.sandbox.mjs +25 -2
- package/static/assets/pdfjs/build/pdf.sandbox.mjs.map +1 -1
- package/static/assets/pdfjs/build/pdf.worker.mjs +140 -16
- package/static/assets/pdfjs/build/pdf.worker.mjs.map +1 -1
- package/static/assets/pdfjs/version +1 -1
- package/static/assets/pdfjs/web/debugger.css +31 -0
- package/static/assets/pdfjs/web/debugger.mjs +144 -2
- package/static/assets/pdfjs/web/images/comment-editButton.svg +6 -1
- package/static/assets/pdfjs/web/locale/ach/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/af/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/an/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/ast/viewer.ftl +0 -60
- package/static/assets/pdfjs/web/locale/az/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/be/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/bg/viewer.ftl +0 -37
- package/static/assets/pdfjs/web/locale/bn/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/bo/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/br/viewer.ftl +0 -37
- package/static/assets/pdfjs/web/locale/brx/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/bs/viewer.ftl +22 -0
- package/static/assets/pdfjs/web/locale/ca/viewer.ftl +0 -54
- package/static/assets/pdfjs/web/locale/cak/viewer.ftl +0 -54
- package/static/assets/pdfjs/web/locale/ckb/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/cs/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/cy/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/da/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/de/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/dsb/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/el/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/en-CA/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/en-GB/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/en-US/viewer.ftl +25 -0
- package/static/assets/pdfjs/web/locale/eo/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/es-AR/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/es-CL/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/es-MX/viewer.ftl +0 -6
- package/static/assets/pdfjs/web/locale/et/viewer.ftl +0 -57
- package/static/assets/pdfjs/web/locale/fa/viewer.ftl +0 -37
- package/static/assets/pdfjs/web/locale/ff/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/fi/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/fr/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/fy-NL/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/ga-IE/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/gd/viewer.ftl +0 -54
- package/static/assets/pdfjs/web/locale/gl/viewer.ftl +8 -0
- package/static/assets/pdfjs/web/locale/gn/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/gu-IN/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/he/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/hi-IN/viewer.ftl +0 -60
- package/static/assets/pdfjs/web/locale/hsb/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/hu/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/hy-AM/viewer.ftl +0 -49
- package/static/assets/pdfjs/web/locale/hye/viewer.ftl +0 -60
- package/static/assets/pdfjs/web/locale/ia/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/is/viewer.ftl +0 -3
- package/static/assets/pdfjs/web/locale/it/viewer.ftl +31 -0
- package/static/assets/pdfjs/web/locale/ja/viewer.ftl +8 -0
- package/static/assets/pdfjs/web/locale/ka/viewer.ftl +48 -10
- package/static/assets/pdfjs/web/locale/kab/viewer.ftl +5 -0
- package/static/assets/pdfjs/web/locale/kk/viewer.ftl +8 -0
- package/static/assets/pdfjs/web/locale/km/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/kn/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/ko/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/lij/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/lo/viewer.ftl +0 -54
- package/static/assets/pdfjs/web/locale/lt/viewer.ftl +0 -60
- package/static/assets/pdfjs/web/locale/ltg/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/lv/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/meh/viewer.ftl +0 -75
- package/static/assets/pdfjs/web/locale/mk/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/ml/viewer.ftl +0 -3
- package/static/assets/pdfjs/web/locale/mr/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/ms/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/my/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/nb-NO/viewer.ftl +44 -6
- package/static/assets/pdfjs/web/locale/ne-NP/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/nl/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/nn-NO/viewer.ftl +45 -1
- package/static/assets/pdfjs/web/locale/oc/viewer.ftl +0 -31
- package/static/assets/pdfjs/web/locale/pa-IN/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/pl/viewer.ftl +39 -1
- package/static/assets/pdfjs/web/locale/pt-BR/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/ro/viewer.ftl +355 -1
- package/static/assets/pdfjs/web/locale/ru/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/sat/viewer.ftl +0 -54
- package/static/assets/pdfjs/web/locale/sc/viewer.ftl +0 -38
- package/static/assets/pdfjs/web/locale/scn/viewer.ftl +0 -92
- package/static/assets/pdfjs/web/locale/sco/viewer.ftl +0 -60
- package/static/assets/pdfjs/web/locale/si/viewer.ftl +0 -51
- package/static/assets/pdfjs/web/locale/sk/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/skr/viewer.ftl +0 -27
- package/static/assets/pdfjs/web/locale/sl/viewer.ftl +8 -0
- package/static/assets/pdfjs/web/locale/son/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/sr/viewer.ftl +0 -33
- package/static/assets/pdfjs/web/locale/sv-SE/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/szl/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/ta/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/te/viewer.ftl +0 -60
- package/static/assets/pdfjs/web/locale/tg/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/tl/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/tr/viewer.ftl +40 -2
- package/static/assets/pdfjs/web/locale/trs/viewer.ftl +0 -72
- package/static/assets/pdfjs/web/locale/ur/viewer.ftl +0 -60
- package/static/assets/pdfjs/web/locale/uz/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/vi/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/wo/viewer.ftl +0 -77
- package/static/assets/pdfjs/web/locale/xh/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/zh-CN/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/zh-TW/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/viewer.css +649 -120
- package/static/assets/pdfjs/web/viewer.html +19 -0
- package/static/assets/pdfjs/web/viewer.mjs +489 -38
- package/static/assets/pdfjs/web/viewer.mjs.map +1 -1
- package/static/chunk-22EANI6R.js +1 -0
- package/static/{chunk-N2LYWNTC.js → chunk-2456KVFZ.js} +1 -1
- package/static/{chunk-YCINY2YI.js → chunk-2LVCLKCK.js} +1 -1
- package/static/{chunk-5YKWZT33.js → chunk-2V5S7DWD.js} +1 -1
- package/static/{chunk-3GC2BQZD.js → chunk-44YDXGNZ.js} +1 -1
- package/static/{chunk-W3QXNDI5.js → chunk-4LSJLWYV.js} +1 -1
- package/static/{chunk-T55FAU2O.js → chunk-4UT5VH7R.js} +1 -1
- package/static/{chunk-VMQMD36Z.js → chunk-5GOMMRRE.js} +1 -1
- package/static/{chunk-TXPODW5Q.js → chunk-5J4VRDKB.js} +1 -1
- package/static/{chunk-FQ4AFNGE.js → chunk-6PVKNZ7Q.js} +1 -1
- package/static/{chunk-XE5YHU5J.js → chunk-BIUNUYZ5.js} +1 -1
- package/static/{chunk-X43VWRFP.js → chunk-DFQKHCDR.js} +1 -1
- package/static/{chunk-TDQAEVZN.js → chunk-EE2TDTY4.js} +1 -1
- package/static/{chunk-MOVWEZ7J.js → chunk-ESNDJ5T6.js} +1 -1
- package/static/{chunk-TCFKH6K6.js → chunk-GDKKLLEU.js} +1 -1
- package/static/{chunk-VHYIXL7R.js → chunk-GSR2MCQG.js} +1 -1
- package/static/{chunk-LJIGRUEF.js → chunk-HR7KS5BR.js} +1 -1
- package/static/chunk-HW2H3ISM.js +559 -0
- package/static/{chunk-HZA7R43P.js → chunk-IMB3C547.js} +1 -1
- package/static/{chunk-B2Y2RNFP.js → chunk-J4ALHUDX.js} +1 -1
- package/static/{chunk-PF4K7MVG.js → chunk-KP6LSQTK.js} +1 -1
- package/static/{chunk-C23BPTJZ.js → chunk-LUZCOHFN.js} +1 -1
- package/static/{chunk-GBCYYDCI.js → chunk-MHSCCXVL.js} +1 -1
- package/static/{chunk-PY3BGNJN.js → chunk-OMRQYBXV.js} +1 -1
- package/static/chunk-P7CTJ5BG.js +27 -0
- package/static/{chunk-Y2CDUS4J.js → chunk-P7PX67IR.js} +4 -4
- package/static/{chunk-VMUOUCEI.js → chunk-PPO7DBVO.js} +1 -1
- package/static/{chunk-TTQ37MUV.js → chunk-RSS6GYNE.js} +1 -1
- package/static/{chunk-WWIC7UW3.js → chunk-SLGGINMR.js} +1 -1
- package/static/{chunk-KZQCFEPT.js → chunk-UHD5XD3G.js} +1 -1
- package/static/{chunk-TNW2CGK6.js → chunk-UPYYAJCJ.js} +1 -1
- package/static/{chunk-6F55D74O.js → chunk-VHYPQ3D4.js} +1 -1
- package/static/{chunk-DGVNNICG.js → chunk-YQSDS6BO.js} +1 -1
- package/static/{chunk-MTRNPGS4.js → chunk-ZC5NIT55.js} +1 -1
- package/static/index.html +1 -1
- package/static/main-FYD34UEC.js +7 -0
- package/static/chunk-RSNLYAN6.js +0 -560
- package/static/chunk-WHMS3PJ3.js +0 -24
- package/static/chunk-ZZ3LHYOY.js +0 -1
- package/static/main-7LDKYVXO.js +0 -10
|
@@ -22,6 +22,7 @@ const _sharesmanagerservice = require("../../shares/services/shares-manager.serv
|
|
|
22
22
|
const _sharesqueriesservice = require("../../shares/services/shares-queries.service");
|
|
23
23
|
const _spacesmanagerservice = require("../../spaces/services/spaces-manager.service");
|
|
24
24
|
const _spacesqueriesservice = require("../../spaces/services/spaces-queries.service");
|
|
25
|
+
const _usermodel = require("../../users/models/user.model");
|
|
25
26
|
const _adminusersmanagerservice = require("../../users/services/admin-users-manager.service");
|
|
26
27
|
const _adminusersqueriesservice = require("../../users/services/admin-users-queries.service");
|
|
27
28
|
const _usersmanagerservice = require("../../users/services/users-manager.service");
|
|
@@ -30,7 +31,47 @@ const _linksmanagerservice = require("./links-manager.service");
|
|
|
30
31
|
const _linksqueriesservice = require("./links-queries.service");
|
|
31
32
|
describe(_linksmanagerservice.LinksManager.name, ()=>{
|
|
32
33
|
let service;
|
|
34
|
+
let linksQueriesMock;
|
|
35
|
+
let usersManagerMock;
|
|
36
|
+
let filesManagerMock;
|
|
37
|
+
let spacesManagerMock;
|
|
38
|
+
let authManagerMock;
|
|
39
|
+
const identity = {
|
|
40
|
+
id: 42,
|
|
41
|
+
login: 'visitor'
|
|
42
|
+
};
|
|
43
|
+
const baseLink = {
|
|
44
|
+
uuid: 'uuid-123',
|
|
45
|
+
user: {
|
|
46
|
+
id: 7,
|
|
47
|
+
login: 'john',
|
|
48
|
+
isActive: true
|
|
49
|
+
},
|
|
50
|
+
requireAuth: false,
|
|
51
|
+
limitAccess: 0,
|
|
52
|
+
nbAccess: 0,
|
|
53
|
+
expiresAt: null
|
|
54
|
+
};
|
|
33
55
|
beforeAll(async ()=>{
|
|
56
|
+
linksQueriesMock = {
|
|
57
|
+
linkFromUUID: jest.fn(),
|
|
58
|
+
spaceLink: jest.fn(),
|
|
59
|
+
incrementLinkNbAccess: jest.fn().mockResolvedValue(undefined)
|
|
60
|
+
};
|
|
61
|
+
usersManagerMock = {
|
|
62
|
+
getAvatarBase64: jest.fn(),
|
|
63
|
+
compareUserPassword: jest.fn(),
|
|
64
|
+
updateAccesses: jest.fn()
|
|
65
|
+
};
|
|
66
|
+
filesManagerMock = {
|
|
67
|
+
sendFileFromSpace: jest.fn()
|
|
68
|
+
};
|
|
69
|
+
spacesManagerMock = {
|
|
70
|
+
spaceEnv: jest.fn()
|
|
71
|
+
};
|
|
72
|
+
authManagerMock = {
|
|
73
|
+
setCookies: jest.fn()
|
|
74
|
+
};
|
|
34
75
|
const module = await _testing.Test.createTestingModule({
|
|
35
76
|
providers: [
|
|
36
77
|
{
|
|
@@ -57,28 +98,351 @@ describe(_linksmanagerservice.LinksManager.name, ()=>{
|
|
|
57
98
|
provide: _fileslockmanagerservice.FilesLockManager,
|
|
58
99
|
useValue: {}
|
|
59
100
|
},
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
101
|
+
{
|
|
102
|
+
provide: _config.ConfigService,
|
|
103
|
+
useValue: {}
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
provide: _jwt.JwtService,
|
|
107
|
+
useValue: {}
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
provide: _authmanagerservice.AuthManager,
|
|
111
|
+
useValue: authManagerMock
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
provide: _usersmanagerservice.UsersManager,
|
|
115
|
+
useValue: usersManagerMock
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
provide: _usersqueriesservice.UsersQueries,
|
|
119
|
+
useValue: {}
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
provide: _adminusersmanagerservice.AdminUsersManager,
|
|
123
|
+
useValue: {}
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
provide: _adminusersqueriesservice.AdminUsersQueries,
|
|
127
|
+
useValue: {}
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
provide: _filesqueriesservice.FilesQueries,
|
|
131
|
+
useValue: {}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
provide: _filesmanagerservice.FilesManager,
|
|
135
|
+
useValue: filesManagerMock
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
provide: _spacesqueriesservice.SpacesQueries,
|
|
139
|
+
useValue: {}
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
provide: _spacesmanagerservice.SpacesManager,
|
|
143
|
+
useValue: spacesManagerMock
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
provide: _sharesqueriesservice.SharesQueries,
|
|
147
|
+
useValue: {}
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
provide: _sharesmanagerservice.SharesManager,
|
|
151
|
+
useValue: {}
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
provide: _linksqueriesservice.LinksQueries,
|
|
155
|
+
useValue: linksQueriesMock
|
|
156
|
+
},
|
|
74
157
|
_linksmanagerservice.LinksManager
|
|
75
158
|
]
|
|
76
159
|
}).compile();
|
|
160
|
+
module.useLogger([
|
|
161
|
+
'fatal'
|
|
162
|
+
]);
|
|
77
163
|
service = module.get(_linksmanagerservice.LinksManager);
|
|
78
164
|
});
|
|
165
|
+
beforeEach(()=>{
|
|
166
|
+
jest.clearAllMocks();
|
|
167
|
+
});
|
|
79
168
|
it('should be defined', ()=>{
|
|
80
169
|
expect(service).toBeDefined();
|
|
81
170
|
});
|
|
171
|
+
describe('linkValidation', ()=>{
|
|
172
|
+
it('returns ok with sanitized owner and avatar when link is valid', async ()=>{
|
|
173
|
+
const link = {
|
|
174
|
+
...baseLink
|
|
175
|
+
};
|
|
176
|
+
linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link);
|
|
177
|
+
const spaceLink = {
|
|
178
|
+
owner: {
|
|
179
|
+
login: 'jane'
|
|
180
|
+
},
|
|
181
|
+
share: {
|
|
182
|
+
isDir: true,
|
|
183
|
+
alias: 's-alias',
|
|
184
|
+
name: 'Docs'
|
|
185
|
+
},
|
|
186
|
+
space: null
|
|
187
|
+
};
|
|
188
|
+
linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink);
|
|
189
|
+
usersManagerMock.getAvatarBase64.mockResolvedValueOnce('base64-avatar');
|
|
190
|
+
const res = await service.linkValidation(identity, link.uuid);
|
|
191
|
+
expect(res.ok).toBe(true);
|
|
192
|
+
expect(res.error).toBeNull();
|
|
193
|
+
expect(res.link).toBe(spaceLink);
|
|
194
|
+
expect(spaceLink.owner.avatar).toBe('base64-avatar');
|
|
195
|
+
expect(spaceLink.owner.login).toBeUndefined();
|
|
196
|
+
expect(linksQueriesMock.spaceLink).toHaveBeenCalledWith(link.uuid);
|
|
197
|
+
// extra coverage: directly assert private checkLink with default ignoreAuth=false
|
|
198
|
+
const directCheck = service.checkLink(identity, link);
|
|
199
|
+
expect(directCheck).toBe(true);
|
|
200
|
+
});
|
|
201
|
+
it('returns error and null link when uuid is not found', async ()=>{
|
|
202
|
+
linksQueriesMock.linkFromUUID.mockResolvedValueOnce(null);
|
|
203
|
+
const res = await service.linkValidation(identity, 'missing-uuid');
|
|
204
|
+
expect(res.ok).toBe(false);
|
|
205
|
+
expect(res.error).toBeDefined();
|
|
206
|
+
expect(res.link).toBeNull();
|
|
207
|
+
});
|
|
208
|
+
it('returns unauthorized when auth is required and identity differs', async ()=>{
|
|
209
|
+
const link = {
|
|
210
|
+
...baseLink,
|
|
211
|
+
requireAuth: true
|
|
212
|
+
};
|
|
213
|
+
linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link);
|
|
214
|
+
const res = await service.linkValidation(identity, link.uuid);
|
|
215
|
+
expect(res.ok).toBe(false);
|
|
216
|
+
expect(String(res.error).toLowerCase()).toContain('unauthorized');
|
|
217
|
+
expect(res.link).toBeNull();
|
|
218
|
+
// extra coverage: directly assert private checkLink with default ignoreAuth=false
|
|
219
|
+
const directCheck = service.checkLink(identity, link);
|
|
220
|
+
expect(String(directCheck).toLowerCase()).toContain('unauthorized');
|
|
221
|
+
});
|
|
222
|
+
it('returns exceeded when nbAccess >= limitAccess', async ()=>{
|
|
223
|
+
const link = {
|
|
224
|
+
...baseLink,
|
|
225
|
+
limitAccess: 5,
|
|
226
|
+
nbAccess: 5
|
|
227
|
+
};
|
|
228
|
+
linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link);
|
|
229
|
+
const res = await service.linkValidation(identity, link.uuid);
|
|
230
|
+
expect(res.ok).toBe(false);
|
|
231
|
+
expect(String(res.error).toLowerCase()).toContain('exceeded');
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
describe('linkAccess', ()=>{
|
|
235
|
+
const req = {
|
|
236
|
+
ip: '127.0.0.1'
|
|
237
|
+
};
|
|
238
|
+
const res = {};
|
|
239
|
+
it('streams a file when link targets a single file', async ()=>{
|
|
240
|
+
const link = {
|
|
241
|
+
...baseLink,
|
|
242
|
+
limitAccess: 10
|
|
243
|
+
};
|
|
244
|
+
linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link);
|
|
245
|
+
const spaceLink = {
|
|
246
|
+
space: null,
|
|
247
|
+
share: {
|
|
248
|
+
isDir: false,
|
|
249
|
+
name: 'file.txt',
|
|
250
|
+
alias: 'share-alias'
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink);
|
|
254
|
+
spacesManagerMock.spaceEnv.mockResolvedValueOnce({});
|
|
255
|
+
const streamable = {
|
|
256
|
+
some: 'stream'
|
|
257
|
+
};
|
|
258
|
+
filesManagerMock.sendFileFromSpace.mockReturnValueOnce({
|
|
259
|
+
checks: jest.fn().mockResolvedValueOnce(undefined),
|
|
260
|
+
stream: jest.fn().mockResolvedValueOnce(streamable)
|
|
261
|
+
});
|
|
262
|
+
// cover: incrementLinkNbAccess.catch(...) should log an error when the query rejects
|
|
263
|
+
const logErrorSpy = jest.spyOn(service.logger, 'error').mockImplementation(()=>undefined);
|
|
264
|
+
linksQueriesMock.incrementLinkNbAccess.mockRejectedValueOnce(new Error('increment boom'));
|
|
265
|
+
const result = await service.linkAccess(identity, link.uuid, req, res);
|
|
266
|
+
expect(result).toBe(streamable);
|
|
267
|
+
expect(filesManagerMock.sendFileFromSpace).toHaveBeenCalled();
|
|
268
|
+
expect(linksQueriesMock.incrementLinkNbAccess).toHaveBeenCalledWith(link.uuid);
|
|
269
|
+
// Assert repository selection for a share file (space falsy)
|
|
270
|
+
// should call spacesManager.spaceEnv with SHARES and share alias when link.space is falsy
|
|
271
|
+
expect(spacesManagerMock.spaceEnv).toHaveBeenCalledWith(expect.anything(), [
|
|
272
|
+
'shares',
|
|
273
|
+
'share-alias'
|
|
274
|
+
]);
|
|
275
|
+
// should log error when increment fails
|
|
276
|
+
expect(logErrorSpy).toHaveBeenCalled();
|
|
277
|
+
});
|
|
278
|
+
it('authenticates and returns cookies when link targets a directory and user is different', async ()=>{
|
|
279
|
+
const link = {
|
|
280
|
+
...baseLink,
|
|
281
|
+
requireAuth: false,
|
|
282
|
+
user: {
|
|
283
|
+
id: 7,
|
|
284
|
+
login: 'john',
|
|
285
|
+
isActive: true
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link);
|
|
289
|
+
const spaceLink = {
|
|
290
|
+
space: {
|
|
291
|
+
alias: 'files',
|
|
292
|
+
name: 'My Space'
|
|
293
|
+
},
|
|
294
|
+
share: {
|
|
295
|
+
isDir: true,
|
|
296
|
+
name: 'ignored',
|
|
297
|
+
alias: 'ignored'
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink);
|
|
301
|
+
const loginDto = {
|
|
302
|
+
token: 'jwt'
|
|
303
|
+
};
|
|
304
|
+
authManagerMock.setCookies.mockResolvedValueOnce(loginDto);
|
|
305
|
+
// cover: usersManager.updateAccesses.catch(...) should log an error when updateAccesses rejects
|
|
306
|
+
const logErrorSpy = jest.spyOn(service.logger, 'error').mockImplementation(()=>undefined);
|
|
307
|
+
usersManagerMock.updateAccesses.mockRejectedValueOnce(new Error('updateAccesses boom'));
|
|
308
|
+
const result = await service.linkAccess(identity, link.uuid, req, res);
|
|
309
|
+
expect(result).toBe(loginDto);
|
|
310
|
+
expect(usersManagerMock.updateAccesses).toHaveBeenCalledWith(expect.anything(), req.ip, true);
|
|
311
|
+
expect(authManagerMock.setCookies).toHaveBeenCalled();
|
|
312
|
+
// additionally cover the "space truthy" branch by calling the private helper directly
|
|
313
|
+
// should call spacesManager.spaceEnv with FILES and space alias when link.space is truthy
|
|
314
|
+
await service.spaceEnvFromLink(new _usermodel.UserModel(link.user), spaceLink);
|
|
315
|
+
expect(spacesManagerMock.spaceEnv).toHaveBeenCalledWith(expect.anything(), [
|
|
316
|
+
'files',
|
|
317
|
+
'files'
|
|
318
|
+
]);
|
|
319
|
+
// should log error when updateAccesses fails
|
|
320
|
+
expect(logErrorSpy).toHaveBeenCalled();
|
|
321
|
+
});
|
|
322
|
+
it('throws BAD_REQUEST when link is invalid', async ()=>{
|
|
323
|
+
const disabledLink = {
|
|
324
|
+
...baseLink,
|
|
325
|
+
user: {
|
|
326
|
+
id: 7,
|
|
327
|
+
login: 'john',
|
|
328
|
+
isActive: false
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
linksQueriesMock.linkFromUUID.mockResolvedValueOnce(disabledLink);
|
|
332
|
+
await expect(service.linkAccess(identity, disabledLink.uuid, req, res)).rejects.toMatchObject({
|
|
333
|
+
status: 400
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
it('returns undefined for already authenticated directory access (same user) and does not set cookies or increment', async ()=>{
|
|
337
|
+
const sameUserIdentity = {
|
|
338
|
+
id: baseLink.user.id,
|
|
339
|
+
login: 'john'
|
|
340
|
+
};
|
|
341
|
+
const link = {
|
|
342
|
+
...baseLink,
|
|
343
|
+
requireAuth: true
|
|
344
|
+
};
|
|
345
|
+
linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link);
|
|
346
|
+
const spaceLink = {
|
|
347
|
+
space: {
|
|
348
|
+
alias: 'files',
|
|
349
|
+
name: 'Space'
|
|
350
|
+
},
|
|
351
|
+
share: {
|
|
352
|
+
isDir: true,
|
|
353
|
+
name: 'dir',
|
|
354
|
+
alias: 'share'
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink);
|
|
358
|
+
const result = await service.linkAccess(sameUserIdentity, link.uuid, req, res);
|
|
359
|
+
expect(result).toBeUndefined();
|
|
360
|
+
expect(authManagerMock.setCookies).not.toHaveBeenCalled();
|
|
361
|
+
expect(linksQueriesMock.incrementLinkNbAccess).not.toHaveBeenCalled();
|
|
362
|
+
});
|
|
363
|
+
it('throws INTERNAL_SERVER_ERROR when file checks fail during streaming', async ()=>{
|
|
364
|
+
const link = {
|
|
365
|
+
...baseLink,
|
|
366
|
+
limitAccess: 10
|
|
367
|
+
};
|
|
368
|
+
linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link);
|
|
369
|
+
const spaceLink = {
|
|
370
|
+
space: null,
|
|
371
|
+
share: {
|
|
372
|
+
isDir: false,
|
|
373
|
+
name: 'bad.txt',
|
|
374
|
+
alias: 'share'
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink);
|
|
378
|
+
spacesManagerMock.spaceEnv.mockResolvedValueOnce({});
|
|
379
|
+
filesManagerMock.sendFileFromSpace.mockReturnValueOnce({
|
|
380
|
+
checks: jest.fn().mockRejectedValueOnce(new Error('disk error')),
|
|
381
|
+
stream: jest.fn()
|
|
382
|
+
});
|
|
383
|
+
await expect(service.linkAccess(identity, link.uuid, req, res)).rejects.toMatchObject({
|
|
384
|
+
status: 500
|
|
385
|
+
});
|
|
386
|
+
expect(linksQueriesMock.incrementLinkNbAccess).toHaveBeenCalledWith(link.uuid);
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
describe('linkAuthentication', ()=>{
|
|
390
|
+
const req = {
|
|
391
|
+
ip: '10.0.0.1'
|
|
392
|
+
};
|
|
393
|
+
const res = {};
|
|
394
|
+
it('returns cookies when password is correct', async ()=>{
|
|
395
|
+
const link = {
|
|
396
|
+
...baseLink,
|
|
397
|
+
requireAuth: true
|
|
398
|
+
};
|
|
399
|
+
linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link);
|
|
400
|
+
usersManagerMock.compareUserPassword.mockResolvedValueOnce(true);
|
|
401
|
+
// usersManagerMock.updateAccesses.mockResolvedValueOnce(undefined) // removed to ensure rejection is hit
|
|
402
|
+
const loginDto = {
|
|
403
|
+
token: 'abc'
|
|
404
|
+
};
|
|
405
|
+
authManagerMock.setCookies.mockResolvedValueOnce(loginDto);
|
|
406
|
+
// cover: usersManager.updateAccesses.catch(...) should log an error when updateAccesses rejects (success flow)
|
|
407
|
+
const logErrorSpy = jest.spyOn(service.logger, 'error').mockImplementation(()=>undefined);
|
|
408
|
+
usersManagerMock.updateAccesses.mockRejectedValueOnce(new Error('updateAccesses auth success boom'));
|
|
409
|
+
const result = await service.linkAuthentication(identity, link.uuid, {
|
|
410
|
+
password: 'secret'
|
|
411
|
+
}, req, res);
|
|
412
|
+
expect(result).toBe(loginDto);
|
|
413
|
+
expect(usersManagerMock.compareUserPassword).toHaveBeenCalledWith(link.user.id, 'secret');
|
|
414
|
+
expect(usersManagerMock.updateAccesses).toHaveBeenCalledWith(expect.anything(), req.ip, true);
|
|
415
|
+
expect(authManagerMock.setCookies).toHaveBeenCalled();
|
|
416
|
+
// should log error when updateAccesses fails in successful authentication
|
|
417
|
+
expect(logErrorSpy).toHaveBeenCalled();
|
|
418
|
+
});
|
|
419
|
+
it('throws FORBIDDEN when password is incorrect', async ()=>{
|
|
420
|
+
const link = {
|
|
421
|
+
...baseLink,
|
|
422
|
+
requireAuth: true
|
|
423
|
+
};
|
|
424
|
+
linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link);
|
|
425
|
+
usersManagerMock.compareUserPassword.mockResolvedValueOnce(false);
|
|
426
|
+
usersManagerMock.updateAccesses.mockResolvedValueOnce(undefined);
|
|
427
|
+
await expect(service.linkAuthentication(identity, link.uuid, {
|
|
428
|
+
password: 'bad'
|
|
429
|
+
}, req, res)).rejects.toMatchObject({
|
|
430
|
+
status: 403
|
|
431
|
+
});
|
|
432
|
+
});
|
|
433
|
+
it('throws BAD_REQUEST when link is invalid (e.g., expired)', async ()=>{
|
|
434
|
+
const expired = {
|
|
435
|
+
...baseLink,
|
|
436
|
+
expiresAt: new Date(Date.now() - 60_000)
|
|
437
|
+
};
|
|
438
|
+
linksQueriesMock.linkFromUUID.mockResolvedValueOnce(expired);
|
|
439
|
+
await expect(service.linkAuthentication(identity, expired.uuid, {
|
|
440
|
+
password: 'whatever'
|
|
441
|
+
}, req, res)).rejects.toMatchObject({
|
|
442
|
+
status: 400
|
|
443
|
+
});
|
|
444
|
+
});
|
|
445
|
+
});
|
|
82
446
|
});
|
|
83
447
|
|
|
84
448
|
//# sourceMappingURL=links-manager.service.spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/links/services/links-manager.service.spec.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 { HttpService } from '@nestjs/axios'\nimport { ConfigService } from '@nestjs/config'\nimport { JwtService } from '@nestjs/jwt'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { AuthManager } from '../../../authentication/services/auth-manager.service'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { ContextManager } from '../../../infrastructure/context/services/context-manager.service'\nimport { DB_TOKEN_PROVIDER } from '../../../infrastructure/database/constants'\nimport { FilesLockManager } from '../../files/services/files-lock-manager.service'\nimport { FilesManager } from '../../files/services/files-manager.service'\nimport { FilesQueries } from '../../files/services/files-queries.service'\nimport { NotificationsManager } from '../../notifications/services/notifications-manager.service'\nimport { SharesManager } from '../../shares/services/shares-manager.service'\nimport { SharesQueries } from '../../shares/services/shares-queries.service'\nimport { SpacesManager } from '../../spaces/services/spaces-manager.service'\nimport { SpacesQueries } from '../../spaces/services/spaces-queries.service'\nimport { AdminUsersManager } from '../../users/services/admin-users-manager.service'\nimport { AdminUsersQueries } from '../../users/services/admin-users-queries.service'\nimport { UsersManager } from '../../users/services/users-manager.service'\nimport { UsersQueries } from '../../users/services/users-queries.service'\nimport { LinksManager } from './links-manager.service'\nimport { LinksQueries } from './links-queries.service'\n\ndescribe(LinksManager.name, () => {\n let service: LinksManager\n\n beforeAll(async () => {\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n {\n provide: DB_TOKEN_PROVIDER,\n useValue: {}\n },\n {\n provide: Cache,\n useValue: {}\n },\n { provide: ContextManager, useValue: {} },\n {\n provide: NotificationsManager,\n useValue: {}\n },\n { provide: HttpService, useValue: {} },\n { provide: FilesLockManager, useValue: {} },\n ConfigService,\n JwtService,\n AuthManager,\n UsersManager,\n UsersQueries,\n AdminUsersManager,\n AdminUsersQueries,\n FilesQueries,\n FilesManager,\n SpacesQueries,\n SpacesManager,\n SharesQueries,\n SharesManager,\n LinksQueries,\n LinksManager\n ]\n }).compile()\n\n service = module.get<LinksManager>(LinksManager)\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n})\n"],"names":["describe","LinksManager","name","service","beforeAll","module","Test","createTestingModule","providers","provide","DB_TOKEN_PROVIDER","useValue","Cache","ContextManager","NotificationsManager","HttpService","FilesLockManager","ConfigService","JwtService","AuthManager","UsersManager","UsersQueries","AdminUsersManager","AdminUsersQueries","FilesQueries","FilesManager","SpacesQueries","SpacesManager","SharesQueries","SharesManager","LinksQueries","compile","get","it","expect","toBeDefined"],"mappings":"AAAA;;;;CAIC;;;;uBAE2B;wBACE;qBACH;yBACS;oCACR;8BACN;uCACS;2BACG;yCACD;qCACJ;qCACA;6CACQ;sCACP;sCACA;sCACA;sCACA;0CACI;0CACA;qCACL;qCACA;qCACA;qCACA;AAE7BA,SAASC,iCAAY,CAACC,IAAI,EAAE;IAC1B,IAAIC;IAEJC,UAAU;QACR,MAAMC,SAAwB,MAAMC,aAAI,CAACC,mBAAmB,CAAC;YAC3DC,WAAW;gBACT;oBACEC,SAASC,4BAAiB;oBAC1BC,UAAU,CAAC;gBACb;gBACA;oBACEF,SAASG,mBAAK;oBACdD,UAAU,CAAC;gBACb;gBACA;oBAAEF,SAASI,qCAAc;oBAAEF,UAAU,CAAC;gBAAE;gBACxC;oBACEF,SAASK,iDAAoB;oBAC7BH,UAAU,CAAC;gBACb;gBACA;oBAAEF,SAASM,kBAAW;oBAAEJ,UAAU,CAAC;gBAAE;gBACrC;oBAAEF,SAASO,yCAAgB;oBAAEL,UAAU,CAAC;gBAAE;gBAC1CM,qBAAa;gBACbC,eAAU;gBACVC,+BAAW;gBACXC,iCAAY;gBACZC,iCAAY;gBACZC,2CAAiB;gBACjBC,2CAAiB;gBACjBC,iCAAY;gBACZC,iCAAY;gBACZC,mCAAa;gBACbC,mCAAa;gBACbC,mCAAa;gBACbC,mCAAa;gBACbC,iCAAY;gBACZ7B,iCAAY;aACb;QACH,GAAG8B,OAAO;QAEV5B,UAAUE,OAAO2B,GAAG,CAAe/B,iCAAY;IACjD;IAEAgC,GAAG,qBAAqB;QACtBC,OAAO/B,SAASgC,WAAW;IAC7B;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/links/services/links-manager.service.spec.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 { HttpService } from '@nestjs/axios'\nimport { ConfigService } from '@nestjs/config'\nimport { JwtService } from '@nestjs/jwt'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { AuthManager } from '../../../authentication/services/auth-manager.service'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { ContextManager } from '../../../infrastructure/context/services/context-manager.service'\nimport { DB_TOKEN_PROVIDER } from '../../../infrastructure/database/constants'\nimport { FilesLockManager } from '../../files/services/files-lock-manager.service'\nimport { FilesManager } from '../../files/services/files-manager.service'\nimport { FilesQueries } from '../../files/services/files-queries.service'\nimport { NotificationsManager } from '../../notifications/services/notifications-manager.service'\nimport { SharesManager } from '../../shares/services/shares-manager.service'\nimport { SharesQueries } from '../../shares/services/shares-queries.service'\nimport { SpacesManager } from '../../spaces/services/spaces-manager.service'\nimport { SpacesQueries } from '../../spaces/services/spaces-queries.service'\nimport { UserModel } from '../../users/models/user.model'\nimport { AdminUsersManager } from '../../users/services/admin-users-manager.service'\nimport { AdminUsersQueries } from '../../users/services/admin-users-queries.service'\nimport { UsersManager } from '../../users/services/users-manager.service'\nimport { UsersQueries } from '../../users/services/users-queries.service'\nimport { LinksManager } from './links-manager.service'\nimport { LinksQueries } from './links-queries.service'\n\ndescribe(LinksManager.name, () => {\n let service: LinksManager\n let linksQueriesMock: jest.Mocked<LinksQueries>\n let usersManagerMock: jest.Mocked<UsersManager>\n let filesManagerMock: jest.Mocked<FilesManager>\n let spacesManagerMock: jest.Mocked<SpacesManager>\n let authManagerMock: jest.Mocked<AuthManager>\n\n const identity: any = { id: 42, login: 'visitor' }\n const baseLink: any = {\n uuid: 'uuid-123',\n user: { id: 7, login: 'john', isActive: true },\n requireAuth: false,\n limitAccess: 0,\n nbAccess: 0,\n expiresAt: null\n }\n\n beforeAll(async () => {\n linksQueriesMock = {\n linkFromUUID: jest.fn(),\n spaceLink: jest.fn(),\n incrementLinkNbAccess: jest.fn().mockResolvedValue(undefined)\n } as any\n\n usersManagerMock = {\n getAvatarBase64: jest.fn(),\n compareUserPassword: jest.fn(),\n updateAccesses: jest.fn()\n } as any\n\n filesManagerMock = {\n sendFileFromSpace: jest.fn()\n } as any\n\n spacesManagerMock = {\n spaceEnv: jest.fn()\n } as any\n\n authManagerMock = {\n setCookies: jest.fn()\n } as any\n\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n {\n provide: DB_TOKEN_PROVIDER,\n useValue: {}\n },\n {\n provide: Cache,\n useValue: {}\n },\n { provide: ContextManager, useValue: {} },\n {\n provide: NotificationsManager,\n useValue: {}\n },\n { provide: HttpService, useValue: {} },\n { provide: FilesLockManager, useValue: {} },\n { provide: ConfigService, useValue: {} },\n { provide: JwtService, useValue: {} },\n { provide: AuthManager, useValue: authManagerMock },\n { provide: UsersManager, useValue: usersManagerMock },\n { provide: UsersQueries, useValue: {} },\n { provide: AdminUsersManager, useValue: {} },\n { provide: AdminUsersQueries, useValue: {} },\n { provide: FilesQueries, useValue: {} },\n { provide: FilesManager, useValue: filesManagerMock },\n { provide: SpacesQueries, useValue: {} },\n { provide: SpacesManager, useValue: spacesManagerMock },\n { provide: SharesQueries, useValue: {} },\n { provide: SharesManager, useValue: {} },\n { provide: LinksQueries, useValue: linksQueriesMock },\n LinksManager\n ]\n }).compile()\n\n module.useLogger(['fatal'])\n service = module.get<LinksManager>(LinksManager)\n })\n\n beforeEach(() => {\n jest.clearAllMocks()\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n\n describe('linkValidation', () => {\n it('returns ok with sanitized owner and avatar when link is valid', async () => {\n const link = { ...baseLink }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n const spaceLink = {\n owner: { login: 'jane' },\n share: { isDir: true, alias: 's-alias', name: 'Docs' },\n space: null\n } as any\n linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink)\n usersManagerMock.getAvatarBase64.mockResolvedValueOnce('base64-avatar')\n\n const res = await service.linkValidation(identity, link.uuid)\n\n expect(res.ok).toBe(true)\n expect(res.error).toBeNull()\n expect(res.link).toBe(spaceLink)\n expect(spaceLink.owner.avatar).toBe('base64-avatar')\n expect((spaceLink.owner as any).login).toBeUndefined()\n expect(linksQueriesMock.spaceLink).toHaveBeenCalledWith(link.uuid)\n\n // extra coverage: directly assert private checkLink with default ignoreAuth=false\n const directCheck = (service as any).checkLink(identity, link)\n expect(directCheck).toBe(true)\n })\n\n it('returns error and null link when uuid is not found', async () => {\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(null)\n\n const res = await service.linkValidation(identity, 'missing-uuid')\n\n expect(res.ok).toBe(false)\n expect(res.error).toBeDefined()\n expect(res.link).toBeNull()\n })\n\n it('returns unauthorized when auth is required and identity differs', async () => {\n const link = { ...baseLink, requireAuth: true }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n\n const res = await service.linkValidation(identity, link.uuid)\n\n expect(res.ok).toBe(false)\n expect(String(res.error).toLowerCase()).toContain('unauthorized')\n expect(res.link).toBeNull()\n\n // extra coverage: directly assert private checkLink with default ignoreAuth=false\n const directCheck = (service as any).checkLink(identity, link)\n expect(String(directCheck).toLowerCase()).toContain('unauthorized')\n })\n\n it('returns exceeded when nbAccess >= limitAccess', async () => {\n const link = { ...baseLink, limitAccess: 5, nbAccess: 5 }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n\n const res = await service.linkValidation(identity, link.uuid)\n\n expect(res.ok).toBe(false)\n expect(String(res.error).toLowerCase()).toContain('exceeded')\n })\n })\n\n describe('linkAccess', () => {\n const req: any = { ip: '127.0.0.1' }\n const res: any = {}\n\n it('streams a file when link targets a single file', async () => {\n const link = { ...baseLink, limitAccess: 10 }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n const spaceLink = {\n space: null,\n share: { isDir: false, name: 'file.txt', alias: 'share-alias' }\n } as any\n linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink)\n\n spacesManagerMock.spaceEnv.mockResolvedValueOnce({} as any)\n const streamable: any = { some: 'stream' }\n filesManagerMock.sendFileFromSpace.mockReturnValueOnce({\n checks: jest.fn().mockResolvedValueOnce(undefined),\n stream: jest.fn().mockResolvedValueOnce(streamable)\n } as any)\n\n // cover: incrementLinkNbAccess.catch(...) should log an error when the query rejects\n const logErrorSpy = jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined as any)\n linksQueriesMock.incrementLinkNbAccess.mockRejectedValueOnce(new Error('increment boom'))\n\n const result = await service.linkAccess(identity, link.uuid, req, res)\n\n expect(result).toBe(streamable)\n expect(filesManagerMock.sendFileFromSpace).toHaveBeenCalled()\n expect(linksQueriesMock.incrementLinkNbAccess).toHaveBeenCalledWith(link.uuid)\n // Assert repository selection for a share file (space falsy)\n // should call spacesManager.spaceEnv with SHARES and share alias when link.space is falsy\n expect(spacesManagerMock.spaceEnv).toHaveBeenCalledWith(expect.anything(), ['shares', 'share-alias'])\n // should log error when increment fails\n expect(logErrorSpy).toHaveBeenCalled()\n })\n\n it('authenticates and returns cookies when link targets a directory and user is different', async () => {\n const link = { ...baseLink, requireAuth: false, user: { id: 7, login: 'john', isActive: true } }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n const spaceLink = {\n space: { alias: 'files', name: 'My Space' },\n share: { isDir: true, name: 'ignored', alias: 'ignored' }\n } as any\n linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink)\n\n const loginDto: any = { token: 'jwt' }\n authManagerMock.setCookies.mockResolvedValueOnce(loginDto)\n\n // cover: usersManager.updateAccesses.catch(...) should log an error when updateAccesses rejects\n const logErrorSpy = jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined as any)\n usersManagerMock.updateAccesses.mockRejectedValueOnce(new Error('updateAccesses boom'))\n\n const result = await service.linkAccess(identity, link.uuid, req, res)\n\n expect(result).toBe(loginDto)\n expect(usersManagerMock.updateAccesses).toHaveBeenCalledWith(expect.anything(), req.ip, true)\n expect(authManagerMock.setCookies).toHaveBeenCalled()\n // additionally cover the \"space truthy\" branch by calling the private helper directly\n // should call spacesManager.spaceEnv with FILES and space alias when link.space is truthy\n await (service as any).spaceEnvFromLink(new UserModel(link.user as any), spaceLink as any)\n expect(spacesManagerMock.spaceEnv).toHaveBeenCalledWith(expect.anything(), ['files', 'files'])\n // should log error when updateAccesses fails\n expect(logErrorSpy).toHaveBeenCalled()\n })\n\n it('throws BAD_REQUEST when link is invalid', async () => {\n const disabledLink = { ...baseLink, user: { id: 7, login: 'john', isActive: false } }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(disabledLink)\n\n await expect(service.linkAccess(identity, disabledLink.uuid, req, res)).rejects.toMatchObject({\n status: 400\n })\n })\n\n it('returns undefined for already authenticated directory access (same user) and does not set cookies or increment', async () => {\n const sameUserIdentity = { id: baseLink.user.id, login: 'john' }\n const link = { ...baseLink, requireAuth: true }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n const spaceLink = {\n space: { alias: 'files', name: 'Space' },\n share: { isDir: true, name: 'dir', alias: 'share' }\n } as any\n linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink)\n\n const result = await service.linkAccess(sameUserIdentity as any, link.uuid, req, res)\n\n expect(result).toBeUndefined()\n expect(authManagerMock.setCookies).not.toHaveBeenCalled()\n expect(linksQueriesMock.incrementLinkNbAccess).not.toHaveBeenCalled()\n })\n\n it('throws INTERNAL_SERVER_ERROR when file checks fail during streaming', async () => {\n const link = { ...baseLink, limitAccess: 10 }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n const spaceLink = {\n space: null,\n share: { isDir: false, name: 'bad.txt', alias: 'share' }\n } as any\n linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink)\n\n spacesManagerMock.spaceEnv.mockResolvedValueOnce({} as any)\n filesManagerMock.sendFileFromSpace.mockReturnValueOnce({\n checks: jest.fn().mockRejectedValueOnce(new Error('disk error')),\n stream: jest.fn()\n } as any)\n\n await expect(service.linkAccess(identity, link.uuid, req, res)).rejects.toMatchObject({\n status: 500\n })\n expect(linksQueriesMock.incrementLinkNbAccess).toHaveBeenCalledWith(link.uuid)\n })\n })\n\n describe('linkAuthentication', () => {\n const req: any = { ip: '10.0.0.1' }\n const res: any = {}\n\n it('returns cookies when password is correct', async () => {\n const link = { ...baseLink, requireAuth: true }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n usersManagerMock.compareUserPassword.mockResolvedValueOnce(true)\n // usersManagerMock.updateAccesses.mockResolvedValueOnce(undefined) // removed to ensure rejection is hit\n const loginDto: any = { token: 'abc' }\n authManagerMock.setCookies.mockResolvedValueOnce(loginDto)\n\n // cover: usersManager.updateAccesses.catch(...) should log an error when updateAccesses rejects (success flow)\n const logErrorSpy = jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined as any)\n usersManagerMock.updateAccesses.mockRejectedValueOnce(new Error('updateAccesses auth success boom'))\n\n const result = await service.linkAuthentication(identity, link.uuid, { password: 'secret' } as any, req, res)\n\n expect(result).toBe(loginDto)\n expect(usersManagerMock.compareUserPassword).toHaveBeenCalledWith(link.user.id, 'secret')\n expect(usersManagerMock.updateAccesses).toHaveBeenCalledWith(expect.anything(), req.ip, true)\n expect(authManagerMock.setCookies).toHaveBeenCalled()\n // should log error when updateAccesses fails in successful authentication\n expect(logErrorSpy).toHaveBeenCalled()\n })\n\n it('throws FORBIDDEN when password is incorrect', async () => {\n const link = { ...baseLink, requireAuth: true }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n usersManagerMock.compareUserPassword.mockResolvedValueOnce(false)\n usersManagerMock.updateAccesses.mockResolvedValueOnce(undefined)\n\n await expect(service.linkAuthentication(identity, link.uuid, { password: 'bad' } as any, req, res)).rejects.toMatchObject({ status: 403 })\n })\n\n it('throws BAD_REQUEST when link is invalid (e.g., expired)', async () => {\n const expired = { ...baseLink, expiresAt: new Date(Date.now() - 60_000) }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(expired)\n\n await expect(service.linkAuthentication(identity, expired.uuid, { password: 'whatever' } as any, req, res)).rejects.toMatchObject({\n status: 400\n })\n })\n })\n})\n"],"names":["describe","LinksManager","name","service","linksQueriesMock","usersManagerMock","filesManagerMock","spacesManagerMock","authManagerMock","identity","id","login","baseLink","uuid","user","isActive","requireAuth","limitAccess","nbAccess","expiresAt","beforeAll","linkFromUUID","jest","fn","spaceLink","incrementLinkNbAccess","mockResolvedValue","undefined","getAvatarBase64","compareUserPassword","updateAccesses","sendFileFromSpace","spaceEnv","setCookies","module","Test","createTestingModule","providers","provide","DB_TOKEN_PROVIDER","useValue","Cache","ContextManager","NotificationsManager","HttpService","FilesLockManager","ConfigService","JwtService","AuthManager","UsersManager","UsersQueries","AdminUsersManager","AdminUsersQueries","FilesQueries","FilesManager","SpacesQueries","SpacesManager","SharesQueries","SharesManager","LinksQueries","compile","useLogger","get","beforeEach","clearAllMocks","it","expect","toBeDefined","link","mockResolvedValueOnce","owner","share","isDir","alias","space","res","linkValidation","ok","toBe","error","toBeNull","avatar","toBeUndefined","toHaveBeenCalledWith","directCheck","checkLink","String","toLowerCase","toContain","req","ip","streamable","some","mockReturnValueOnce","checks","stream","logErrorSpy","spyOn","logger","mockImplementation","mockRejectedValueOnce","Error","result","linkAccess","toHaveBeenCalled","anything","loginDto","token","spaceEnvFromLink","UserModel","disabledLink","rejects","toMatchObject","status","sameUserIdentity","not","linkAuthentication","password","expired","Date","now"],"mappings":"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"}
|
|
@@ -137,7 +137,7 @@ let LinksQueries = class LinksQueries {
|
|
|
137
137
|
}).from(_linksschema.links).leftJoin(_sharesmembersschema.sharesMembers, (0, _drizzleorm.eq)(_sharesmembersschema.sharesMembers.linkId, _linksschema.links.id)).leftJoin(_sharesschema.shares, (0, _drizzleorm.eq)(_sharesschema.shares.id, _sharesmembersschema.sharesMembers.shareId)).leftJoin(shareOwner, (0, _drizzleorm.eq)(shareOwner.id, _sharesschema.shares.ownerId)).leftJoin(_spacesmembersschema.spacesMembers, (0, _drizzleorm.eq)(_spacesmembersschema.spacesMembers.linkId, _linksschema.links.id)).leftJoin(_spacesschema.spaces, (0, _drizzleorm.eq)(_spacesschema.spaces.id, _spacesmembersschema.spacesMembers.spaceId)).leftJoin(shareSpaceRoot, (0, _drizzleorm.and)((0, _drizzleorm.isNull)(_sharesschema.shares.externalPath), (0, _drizzleorm.isNull)(_sharesschema.shares.fileId), (0, _drizzleorm.eq)(shareSpaceRoot.id, _sharesschema.shares.spaceRootId))).leftJoin(_filesschema.files, (0, _drizzleorm.or)((0, _drizzleorm.and)((0, _drizzleorm.isNotNull)(_sharesschema.shares.fileId), (0, _drizzleorm.eq)(_filesschema.files.id, _sharesschema.shares.fileId)), (0, _drizzleorm.and)((0, _drizzleorm.isNull)(_sharesschema.shares.externalPath), (0, _drizzleorm.isNotNull)(shareSpaceRoot.fileId), (0, _drizzleorm.eq)(_filesschema.files.id, shareSpaceRoot.fileId)))).where((0, _drizzleorm.eq)(_linksschema.links.uuid, uuid)).limit(1);
|
|
138
138
|
return r;
|
|
139
139
|
}
|
|
140
|
-
async
|
|
140
|
+
async incrementLinkNbAccess(uuid) {
|
|
141
141
|
await this.db.update(_linksschema.links).set({
|
|
142
142
|
nbAccess: (0, _drizzleorm.sql)`${_linksschema.links.nbAccess} + 1`
|
|
143
143
|
}).where((0, _drizzleorm.eq)(_linksschema.links.uuid, uuid)).limit(1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/links/services/links-queries.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 { Inject, Injectable } from '@nestjs/common'\nimport { and, eq, getTableColumns, isNotNull, isNull, or, sql } from 'drizzle-orm'\nimport { alias } from 'drizzle-orm/mysql-core'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { DB_TOKEN_PROVIDER } from '../../../infrastructure/database/constants'\nimport type { DBSchema } from '../../../infrastructure/database/interfaces/database.interface'\nimport { dbGetInsertedId } from '../../../infrastructure/database/utils'\nimport { files } from '../../files/schemas/files.schema'\nimport type { ShareMembers } from '../../shares/schemas/share-members.interface'\nimport type { Share } from '../../shares/schemas/share.interface'\nimport { sharesMembers } from '../../shares/schemas/shares-members.schema'\nimport { shares } from '../../shares/schemas/shares.schema'\nimport { SPACE_ROLE } from '../../spaces/constants/spaces'\nimport type { SpaceMembers } from '../../spaces/schemas/space-members.interface'\nimport { spacesMembers } from '../../spaces/schemas/spaces-members.schema'\nimport { spacesRoots } from '../../spaces/schemas/spaces-roots.schema'\nimport { spaces } from '../../spaces/schemas/spaces.schema'\nimport { USER_ROLE } from '../../users/constants/user'\nimport type { User } from '../../users/schemas/user.interface'\nimport { userFullNameSQL, users } from '../../users/schemas/users.schema'\nimport { CACHE_LINK_UUID_PREFIX, CACHE_LINK_UUID_TTL } from '../constants/cache'\nimport { LINK_TYPE } from '../constants/links'\nimport type { LinkAsUser, LinkGuest } from '../interfaces/link-guest.interface'\nimport type { SpaceLink } from '../interfaces/link-space.interface'\nimport type { Link } from '../schemas/link.interface'\nimport { links } from '../schemas/links.schema'\n\n@Injectable()\nexport class LinksQueries {\n constructor(\n @Inject(DB_TOKEN_PROVIDER) private readonly db: DBSchema,\n private readonly cache: Cache\n ) {}\n\n async linkFromShare(ownerId: number, linkId: number, shareId: number, isAdmin: number = 0): Promise<LinkGuest> {\n const [r] = await this.db\n .select({\n ...getTableColumns(links),\n permissions: sharesMembers.permissions,\n language: users.language,\n isActive: users.isActive\n })\n .from(links)\n .innerJoin(shares, and(eq(shares.id, shareId), or(eq(shares.ownerId, ownerId), and(eq(sql`${isAdmin}`, 1), isNull(shares.ownerId)))))\n .innerJoin(sharesMembers, and(eq(sharesMembers.shareId, shares.id), eq(sharesMembers.userId, links.userId), eq(sharesMembers.linkId, linkId)))\n .innerJoin(users, eq(users.id, links.userId))\n .where(eq(links.id, linkId))\n .limit(1)\n return r as LinkGuest\n }\n\n async linkFromSpace(managerId: number, linkId: number, spaceId: number): Promise<LinkGuest> {\n const linkMember: any = alias(spacesMembers, 'linkMember')\n const [r] = await this.db\n .select({\n ...getTableColumns(links),\n permissions: linkMember.permissions,\n language: users.language,\n isActive: users.isActive\n })\n .from(links)\n .innerJoin(\n spacesMembers,\n and(eq(spacesMembers.spaceId, spaceId), eq(spacesMembers.userId, managerId), eq(spacesMembers.role, SPACE_ROLE.IS_MANAGER))\n )\n .innerJoin(linkMember, and(eq(linkMember.spaceId, spacesMembers.spaceId), eq(linkMember.userId, links.userId), eq(linkMember.linkId, linkId)))\n .innerJoin(users, eq(users.id, links.userId))\n .where(eq(links.id, linkId))\n .limit(1)\n return r as LinkGuest\n }\n\n async updateLinkFromSpaceOrShare(\n link: LinkGuest,\n shareId: number,\n diffUser: Partial<User>,\n diffLink: Partial<Link>,\n diffShare: Partial<Share>,\n diffMember: Partial<ShareMembers>\n ) {\n if (Object.keys(diffUser).length) {\n await this.db.update(users).set(diffUser).where(eq(users.id, link.userId))\n }\n if (Object.keys(diffLink).length) {\n await this.db.update(links).set(diffLink).where(eq(links.id, link.id))\n }\n if (Object.keys(diffShare).length) {\n await this.db.update(shares).set(diffShare).where(eq(shares.id, shareId))\n }\n if (Object.keys(diffMember).length) {\n await this.db\n .update(sharesMembers)\n .set(diffMember)\n .where(and(eq(sharesMembers.shareId, shareId), eq(sharesMembers.userId, link.userId), eq(sharesMembers.linkId, link.id)))\n }\n }\n\n async createLinkToSpaceOrShare(guestId: number, spaceOrShareId: number, type: LINK_TYPE, link: Partial<LinkGuest>): Promise<number> {\n const linkId = dbGetInsertedId(await this.db.insert(links).values(link as Link))\n if (type === LINK_TYPE.SPACE) {\n await this.db.insert(spacesMembers).values({\n userId: guestId,\n spaceId: spaceOrShareId,\n permissions: link.permissions,\n role: SPACE_ROLE.IS_MEMBER,\n linkId: linkId\n } as SpaceMembers)\n } else {\n await this.db.insert(sharesMembers).values({\n userId: guestId,\n shareId: spaceOrShareId,\n linkId: linkId,\n permissions: link.permissions\n } as ShareMembers)\n }\n return linkId\n }\n\n allLinksFromSpaceOrShare(spaceOrShareId: number, type: LINK_TYPE): Promise<{ id: number; linkId: number }[]> {\n const members: any = alias(type == 'share' ? sharesMembers : spacesMembers, 'members')\n return this.db\n .select({ id: users.id, linkId: members.linkId })\n .from(members)\n .innerJoin(users, and(eq(users.id, members.userId), eq(users.role, USER_ROLE.LINK)))\n .where(and(eq(type == 'share' ? members.shareId : members.spaceId, spaceOrShareId), isNotNull(members.linkId)))\n }\n\n async linkFromUUID(uuid: string): Promise<LinkAsUser> {\n const { password, ...userColumns } = getTableColumns(users)\n const [r] = await this.db\n .select({\n ...getTableColumns(links),\n user: { ...userColumns }\n })\n .from(links)\n .leftJoin(users, eq(users.id, links.userId))\n .where(eq(links.uuid, uuid))\n .limit(1)\n return r\n }\n\n async spaceLink(uuid: string): Promise<SpaceLink> {\n const shareOwner: any = alias(users, 'shareOwner')\n const shareSpaceRoot: any = alias(spacesRoots, 'shareSpaceRoot')\n const [r]: SpaceLink[] = await this.db\n .select({\n share: {\n name: shares.name,\n alias: shares.alias,\n hasParent: isNotNull(shares.parentId).mapWith(Boolean),\n isDir: sql`IF (${isNotNull(shares.externalPath)}, 1 ,${files.isDir})`.mapWith(Boolean),\n mime: files.mime\n },\n space: { name: spaces.name, alias: spaces.alias },\n owner: { login: shareOwner.login, fullName: userFullNameSQL(shareOwner) }\n })\n .from(links)\n .leftJoin(sharesMembers, eq(sharesMembers.linkId, links.id))\n .leftJoin(shares, eq(shares.id, sharesMembers.shareId))\n .leftJoin(shareOwner, eq(shareOwner.id, shares.ownerId))\n .leftJoin(spacesMembers, eq(spacesMembers.linkId, links.id))\n .leftJoin(spaces, eq(spaces.id, spacesMembers.spaceId))\n .leftJoin(shareSpaceRoot, and(isNull(shares.externalPath), isNull(shares.fileId), eq(shareSpaceRoot.id, shares.spaceRootId)))\n .leftJoin(\n files,\n or(\n and(isNotNull(shares.fileId), eq(files.id, shares.fileId)),\n and(isNull(shares.externalPath), isNotNull(shareSpaceRoot.fileId), eq(files.id, shareSpaceRoot.fileId))\n )\n )\n .where(eq(links.uuid, uuid))\n .limit(1)\n return r\n }\n\n async incrementLinkAccess(uuid: string) {\n await this.db\n .update(links)\n .set({ nbAccess: sql`${links.nbAccess} + 1` } as Record<keyof Link, any>)\n .where(eq(links.uuid, uuid))\n .limit(1)\n }\n\n async isUniqueUUID(userId: number, uuid: string) {\n const [r] = await this.db.select({ check: links.uuid }).from(links).where(eq(links.uuid, uuid)).limit(1)\n if (!r) {\n // uuid does not exist in db\n const cacheKey = this.cache.genSlugKey(CACHE_LINK_UUID_PREFIX, userId, uuid)\n // check if uuid was already requested\n if (!(await this.cache.has(cacheKey))) {\n // store uuid to prevent reuse\n await this.cache.set(cacheKey, uuid, CACHE_LINK_UUID_TTL)\n return true\n }\n return false\n }\n return false\n }\n\n isReservedUUID(userId: number, uuid: string): Promise<boolean> {\n // check if uuid is reserved\n return this.cache.has(this.cache.genSlugKey(CACHE_LINK_UUID_PREFIX, userId, uuid))\n }\n}\n"],"names":["LinksQueries","linkFromShare","ownerId","linkId","shareId","isAdmin","r","db","select","getTableColumns","links","permissions","sharesMembers","language","users","isActive","from","innerJoin","shares","and","eq","id","or","sql","isNull","userId","where","limit","linkFromSpace","managerId","spaceId","linkMember","alias","spacesMembers","role","SPACE_ROLE","IS_MANAGER","updateLinkFromSpaceOrShare","link","diffUser","diffLink","diffShare","diffMember","Object","keys","length","update","set","createLinkToSpaceOrShare","guestId","spaceOrShareId","type","dbGetInsertedId","insert","values","LINK_TYPE","SPACE","IS_MEMBER","allLinksFromSpaceOrShare","members","USER_ROLE","LINK","isNotNull","linkFromUUID","uuid","password","userColumns","user","leftJoin","spaceLink","shareOwner","shareSpaceRoot","spacesRoots","share","name","hasParent","parentId","mapWith","Boolean","isDir","externalPath","files","mime","space","spaces","owner","login","fullName","userFullNameSQL","fileId","spaceRootId","incrementLinkAccess","nbAccess","isUniqueUUID","check","cacheKey","cache","genSlugKey","CACHE_LINK_UUID_PREFIX","has","CACHE_LINK_UUID_TTL","isReservedUUID"],"mappings":"AAAA;;;;CAIC;;;;+BA8BYA;;;eAAAA;;;wBA5BsB;4BACkC;2BAC/C;8BACA;2BACY;uBAEF;6BACV;qCAGQ;8BACP;wBACI;qCAEG;mCACF;8BACL;sBACG;6BAEa;uBACqB;uBAClC;6BAIJ;;;;;;;;;;;;;;;AAGf,IAAA,AAAMA,eAAN,MAAMA;IAMX,MAAMC,cAAcC,OAAe,EAAEC,MAAc,EAAEC,OAAe,EAAEC,UAAkB,CAAC,EAAsB;QAC7G,MAAM,CAACC,EAAE,GAAG,MAAM,IAAI,CAACC,EAAE,CACtBC,MAAM,CAAC;YACN,GAAGC,IAAAA,2BAAe,EAACC,kBAAK,CAAC;YACzBC,aAAaC,kCAAa,CAACD,WAAW;YACtCE,UAAUC,kBAAK,CAACD,QAAQ;YACxBE,UAAUD,kBAAK,CAACC,QAAQ;QAC1B,GACCC,IAAI,CAACN,kBAAK,EACVO,SAAS,CAACC,oBAAM,EAAEC,IAAAA,eAAG,EAACC,IAAAA,cAAE,EAACF,oBAAM,CAACG,EAAE,EAAEjB,UAAUkB,IAAAA,cAAE,EAACF,IAAAA,cAAE,EAACF,oBAAM,CAAChB,OAAO,EAAEA,UAAUiB,IAAAA,eAAG,EAACC,IAAAA,cAAE,EAACG,IAAAA,eAAG,CAAA,CAAC,EAAElB,QAAQ,CAAC,EAAE,IAAImB,IAAAA,kBAAM,EAACN,oBAAM,CAAChB,OAAO,MAC/He,SAAS,CAACL,kCAAa,EAAEO,IAAAA,eAAG,EAACC,IAAAA,cAAE,EAACR,kCAAa,CAACR,OAAO,EAAEc,oBAAM,CAACG,EAAE,GAAGD,IAAAA,cAAE,EAACR,kCAAa,CAACa,MAAM,EAAEf,kBAAK,CAACe,MAAM,GAAGL,IAAAA,cAAE,EAACR,kCAAa,CAACT,MAAM,EAAEA,UACpIc,SAAS,CAACH,kBAAK,EAAEM,IAAAA,cAAE,EAACN,kBAAK,CAACO,EAAE,EAAEX,kBAAK,CAACe,MAAM,GAC1CC,KAAK,CAACN,IAAAA,cAAE,EAACV,kBAAK,CAACW,EAAE,EAAElB,SACnBwB,KAAK,CAAC;QACT,OAAOrB;IACT;IAEA,MAAMsB,cAAcC,SAAiB,EAAE1B,MAAc,EAAE2B,OAAe,EAAsB;QAC1F,MAAMC,aAAkBC,IAAAA,gBAAK,EAACC,kCAAa,EAAE;QAC7C,MAAM,CAAC3B,EAAE,GAAG,MAAM,IAAI,CAACC,EAAE,CACtBC,MAAM,CAAC;YACN,GAAGC,IAAAA,2BAAe,EAACC,kBAAK,CAAC;YACzBC,aAAaoB,WAAWpB,WAAW;YACnCE,UAAUC,kBAAK,CAACD,QAAQ;YACxBE,UAAUD,kBAAK,CAACC,QAAQ;QAC1B,GACCC,IAAI,CAACN,kBAAK,EACVO,SAAS,CACRgB,kCAAa,EACbd,IAAAA,eAAG,EAACC,IAAAA,cAAE,EAACa,kCAAa,CAACH,OAAO,EAAEA,UAAUV,IAAAA,cAAE,EAACa,kCAAa,CAACR,MAAM,EAAEI,YAAYT,IAAAA,cAAE,EAACa,kCAAa,CAACC,IAAI,EAAEC,kBAAU,CAACC,UAAU,IAE1HnB,SAAS,CAACc,YAAYZ,IAAAA,eAAG,EAACC,IAAAA,cAAE,EAACW,WAAWD,OAAO,EAAEG,kCAAa,CAACH,OAAO,GAAGV,IAAAA,cAAE,EAACW,WAAWN,MAAM,EAAEf,kBAAK,CAACe,MAAM,GAAGL,IAAAA,cAAE,EAACW,WAAW5B,MAAM,EAAEA,UACpIc,SAAS,CAACH,kBAAK,EAAEM,IAAAA,cAAE,EAACN,kBAAK,CAACO,EAAE,EAAEX,kBAAK,CAACe,MAAM,GAC1CC,KAAK,CAACN,IAAAA,cAAE,EAACV,kBAAK,CAACW,EAAE,EAAElB,SACnBwB,KAAK,CAAC;QACT,OAAOrB;IACT;IAEA,MAAM+B,2BACJC,IAAe,EACflC,OAAe,EACfmC,QAAuB,EACvBC,QAAuB,EACvBC,SAAyB,EACzBC,UAAiC,EACjC;QACA,IAAIC,OAAOC,IAAI,CAACL,UAAUM,MAAM,EAAE;YAChC,MAAM,IAAI,CAACtC,EAAE,CAACuC,MAAM,CAAChC,kBAAK,EAAEiC,GAAG,CAACR,UAAUb,KAAK,CAACN,IAAAA,cAAE,EAACN,kBAAK,CAACO,EAAE,EAAEiB,KAAKb,MAAM;QAC1E;QACA,IAAIkB,OAAOC,IAAI,CAACJ,UAAUK,MAAM,EAAE;YAChC,MAAM,IAAI,CAACtC,EAAE,CAACuC,MAAM,CAACpC,kBAAK,EAAEqC,GAAG,CAACP,UAAUd,KAAK,CAACN,IAAAA,cAAE,EAACV,kBAAK,CAACW,EAAE,EAAEiB,KAAKjB,EAAE;QACtE;QACA,IAAIsB,OAAOC,IAAI,CAACH,WAAWI,MAAM,EAAE;YACjC,MAAM,IAAI,CAACtC,EAAE,CAACuC,MAAM,CAAC5B,oBAAM,EAAE6B,GAAG,CAACN,WAAWf,KAAK,CAACN,IAAAA,cAAE,EAACF,oBAAM,CAACG,EAAE,EAAEjB;QAClE;QACA,IAAIuC,OAAOC,IAAI,CAACF,YAAYG,MAAM,EAAE;YAClC,MAAM,IAAI,CAACtC,EAAE,CACVuC,MAAM,CAAClC,kCAAa,EACpBmC,GAAG,CAACL,YACJhB,KAAK,CAACP,IAAAA,eAAG,EAACC,IAAAA,cAAE,EAACR,kCAAa,CAACR,OAAO,EAAEA,UAAUgB,IAAAA,cAAE,EAACR,kCAAa,CAACa,MAAM,EAAEa,KAAKb,MAAM,GAAGL,IAAAA,cAAE,EAACR,kCAAa,CAACT,MAAM,EAAEmC,KAAKjB,EAAE;QAC1H;IACF;IAEA,MAAM2B,yBAAyBC,OAAe,EAAEC,cAAsB,EAAEC,IAAe,EAAEb,IAAwB,EAAmB;QAClI,MAAMnC,SAASiD,IAAAA,sBAAe,EAAC,MAAM,IAAI,CAAC7C,EAAE,CAAC8C,MAAM,CAAC3C,kBAAK,EAAE4C,MAAM,CAAChB;QAClE,IAAIa,SAASI,gBAAS,CAACC,KAAK,EAAE;YAC5B,MAAM,IAAI,CAACjD,EAAE,CAAC8C,MAAM,CAACpB,kCAAa,EAAEqB,MAAM,CAAC;gBACzC7B,QAAQwB;gBACRnB,SAASoB;gBACTvC,aAAa2B,KAAK3B,WAAW;gBAC7BuB,MAAMC,kBAAU,CAACsB,SAAS;gBAC1BtD,QAAQA;YACV;QACF,OAAO;YACL,MAAM,IAAI,CAACI,EAAE,CAAC8C,MAAM,CAACzC,kCAAa,EAAE0C,MAAM,CAAC;gBACzC7B,QAAQwB;gBACR7C,SAAS8C;gBACT/C,QAAQA;gBACRQ,aAAa2B,KAAK3B,WAAW;YAC/B;QACF;QACA,OAAOR;IACT;IAEAuD,yBAAyBR,cAAsB,EAAEC,IAAe,EAA6C;QAC3G,MAAMQ,UAAe3B,IAAAA,gBAAK,EAACmB,QAAQ,UAAUvC,kCAAa,GAAGqB,kCAAa,EAAE;QAC5E,OAAO,IAAI,CAAC1B,EAAE,CACXC,MAAM,CAAC;YAAEa,IAAIP,kBAAK,CAACO,EAAE;YAAElB,QAAQwD,QAAQxD,MAAM;QAAC,GAC9Ca,IAAI,CAAC2C,SACL1C,SAAS,CAACH,kBAAK,EAAEK,IAAAA,eAAG,EAACC,IAAAA,cAAE,EAACN,kBAAK,CAACO,EAAE,EAAEsC,QAAQlC,MAAM,GAAGL,IAAAA,cAAE,EAACN,kBAAK,CAACoB,IAAI,EAAE0B,eAAS,CAACC,IAAI,IAChFnC,KAAK,CAACP,IAAAA,eAAG,EAACC,IAAAA,cAAE,EAAC+B,QAAQ,UAAUQ,QAAQvD,OAAO,GAAGuD,QAAQ7B,OAAO,EAAEoB,iBAAiBY,IAAAA,qBAAS,EAACH,QAAQxD,MAAM;IAChH;IAEA,MAAM4D,aAAaC,IAAY,EAAuB;QACpD,MAAM,EAAEC,QAAQ,EAAE,GAAGC,aAAa,GAAGzD,IAAAA,2BAAe,EAACK,kBAAK;QAC1D,MAAM,CAACR,EAAE,GAAG,MAAM,IAAI,CAACC,EAAE,CACtBC,MAAM,CAAC;YACN,GAAGC,IAAAA,2BAAe,EAACC,kBAAK,CAAC;YACzByD,MAAM;gBAAE,GAAGD,WAAW;YAAC;QACzB,GACClD,IAAI,CAACN,kBAAK,EACV0D,QAAQ,CAACtD,kBAAK,EAAEM,IAAAA,cAAE,EAACN,kBAAK,CAACO,EAAE,EAAEX,kBAAK,CAACe,MAAM,GACzCC,KAAK,CAACN,IAAAA,cAAE,EAACV,kBAAK,CAACsD,IAAI,EAAEA,OACrBrC,KAAK,CAAC;QACT,OAAOrB;IACT;IAEA,MAAM+D,UAAUL,IAAY,EAAsB;QAChD,MAAMM,aAAkBtC,IAAAA,gBAAK,EAAClB,kBAAK,EAAE;QACrC,MAAMyD,iBAAsBvC,IAAAA,gBAAK,EAACwC,8BAAW,EAAE;QAC/C,MAAM,CAAClE,EAAE,GAAgB,MAAM,IAAI,CAACC,EAAE,CACnCC,MAAM,CAAC;YACNiE,OAAO;gBACLC,MAAMxD,oBAAM,CAACwD,IAAI;gBACjB1C,OAAOd,oBAAM,CAACc,KAAK;gBACnB2C,WAAWb,IAAAA,qBAAS,EAAC5C,oBAAM,CAAC0D,QAAQ,EAAEC,OAAO,CAACC;gBAC9CC,OAAOxD,IAAAA,eAAG,CAAA,CAAC,IAAI,EAAEuC,IAAAA,qBAAS,EAAC5C,oBAAM,CAAC8D,YAAY,EAAE,KAAK,EAAEC,kBAAK,CAACF,KAAK,CAAC,CAAC,CAAC,CAACF,OAAO,CAACC;gBAC9EI,MAAMD,kBAAK,CAACC,IAAI;YAClB;YACAC,OAAO;gBAAET,MAAMU,oBAAM,CAACV,IAAI;gBAAE1C,OAAOoD,oBAAM,CAACpD,KAAK;YAAC;YAChDqD,OAAO;gBAAEC,OAAOhB,WAAWgB,KAAK;gBAAEC,UAAUC,IAAAA,4BAAe,EAAClB;YAAY;QAC1E,GACCtD,IAAI,CAACN,kBAAK,EACV0D,QAAQ,CAACxD,kCAAa,EAAEQ,IAAAA,cAAE,EAACR,kCAAa,CAACT,MAAM,EAAEO,kBAAK,CAACW,EAAE,GACzD+C,QAAQ,CAAClD,oBAAM,EAAEE,IAAAA,cAAE,EAACF,oBAAM,CAACG,EAAE,EAAET,kCAAa,CAACR,OAAO,GACpDgE,QAAQ,CAACE,YAAYlD,IAAAA,cAAE,EAACkD,WAAWjD,EAAE,EAAEH,oBAAM,CAAChB,OAAO,GACrDkE,QAAQ,CAACnC,kCAAa,EAAEb,IAAAA,cAAE,EAACa,kCAAa,CAAC9B,MAAM,EAAEO,kBAAK,CAACW,EAAE,GACzD+C,QAAQ,CAACgB,oBAAM,EAAEhE,IAAAA,cAAE,EAACgE,oBAAM,CAAC/D,EAAE,EAAEY,kCAAa,CAACH,OAAO,GACpDsC,QAAQ,CAACG,gBAAgBpD,IAAAA,eAAG,EAACK,IAAAA,kBAAM,EAACN,oBAAM,CAAC8D,YAAY,GAAGxD,IAAAA,kBAAM,EAACN,oBAAM,CAACuE,MAAM,GAAGrE,IAAAA,cAAE,EAACmD,eAAelD,EAAE,EAAEH,oBAAM,CAACwE,WAAW,IACzHtB,QAAQ,CACPa,kBAAK,EACL3D,IAAAA,cAAE,EACAH,IAAAA,eAAG,EAAC2C,IAAAA,qBAAS,EAAC5C,oBAAM,CAACuE,MAAM,GAAGrE,IAAAA,cAAE,EAAC6D,kBAAK,CAAC5D,EAAE,EAAEH,oBAAM,CAACuE,MAAM,IACxDtE,IAAAA,eAAG,EAACK,IAAAA,kBAAM,EAACN,oBAAM,CAAC8D,YAAY,GAAGlB,IAAAA,qBAAS,EAACS,eAAekB,MAAM,GAAGrE,IAAAA,cAAE,EAAC6D,kBAAK,CAAC5D,EAAE,EAAEkD,eAAekB,MAAM,KAGxG/D,KAAK,CAACN,IAAAA,cAAE,EAACV,kBAAK,CAACsD,IAAI,EAAEA,OACrBrC,KAAK,CAAC;QACT,OAAOrB;IACT;IAEA,MAAMqF,oBAAoB3B,IAAY,EAAE;QACtC,MAAM,IAAI,CAACzD,EAAE,CACVuC,MAAM,CAACpC,kBAAK,EACZqC,GAAG,CAAC;YAAE6C,UAAUrE,IAAAA,eAAG,CAAA,CAAC,EAAEb,kBAAK,CAACkF,QAAQ,CAAC,IAAI,CAAC;QAAC,GAC3ClE,KAAK,CAACN,IAAAA,cAAE,EAACV,kBAAK,CAACsD,IAAI,EAAEA,OACrBrC,KAAK,CAAC;IACX;IAEA,MAAMkE,aAAapE,MAAc,EAAEuC,IAAY,EAAE;QAC/C,MAAM,CAAC1D,EAAE,GAAG,MAAM,IAAI,CAACC,EAAE,CAACC,MAAM,CAAC;YAAEsF,OAAOpF,kBAAK,CAACsD,IAAI;QAAC,GAAGhD,IAAI,CAACN,kBAAK,EAAEgB,KAAK,CAACN,IAAAA,cAAE,EAACV,kBAAK,CAACsD,IAAI,EAAEA,OAAOrC,KAAK,CAAC;QACtG,IAAI,CAACrB,GAAG;YACN,4BAA4B;YAC5B,MAAMyF,WAAW,IAAI,CAACC,KAAK,CAACC,UAAU,CAACC,6BAAsB,EAAEzE,QAAQuC;YACvE,sCAAsC;YACtC,IAAI,CAAE,MAAM,IAAI,CAACgC,KAAK,CAACG,GAAG,CAACJ,WAAY;gBACrC,8BAA8B;gBAC9B,MAAM,IAAI,CAACC,KAAK,CAACjD,GAAG,CAACgD,UAAU/B,MAAMoC,0BAAmB;gBACxD,OAAO;YACT;YACA,OAAO;QACT;QACA,OAAO;IACT;IAEAC,eAAe5E,MAAc,EAAEuC,IAAY,EAAoB;QAC7D,4BAA4B;QAC5B,OAAO,IAAI,CAACgC,KAAK,CAACG,GAAG,CAAC,IAAI,CAACH,KAAK,CAACC,UAAU,CAACC,6BAAsB,EAAEzE,QAAQuC;IAC9E;IA7KA,YACE,AAA4CzD,EAAY,EACxD,AAAiByF,KAAY,CAC7B;aAF4CzF,KAAAA;aAC3ByF,QAAAA;IAChB;AA2KL"}
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/links/services/links-queries.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 { Inject, Injectable } from '@nestjs/common'\nimport { and, eq, getTableColumns, isNotNull, isNull, or, sql } from 'drizzle-orm'\nimport { alias } from 'drizzle-orm/mysql-core'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { DB_TOKEN_PROVIDER } from '../../../infrastructure/database/constants'\nimport type { DBSchema } from '../../../infrastructure/database/interfaces/database.interface'\nimport { dbGetInsertedId } from '../../../infrastructure/database/utils'\nimport { files } from '../../files/schemas/files.schema'\nimport type { ShareMembers } from '../../shares/schemas/share-members.interface'\nimport type { Share } from '../../shares/schemas/share.interface'\nimport { sharesMembers } from '../../shares/schemas/shares-members.schema'\nimport { shares } from '../../shares/schemas/shares.schema'\nimport { SPACE_ROLE } from '../../spaces/constants/spaces'\nimport type { SpaceMembers } from '../../spaces/schemas/space-members.interface'\nimport { spacesMembers } from '../../spaces/schemas/spaces-members.schema'\nimport { spacesRoots } from '../../spaces/schemas/spaces-roots.schema'\nimport { spaces } from '../../spaces/schemas/spaces.schema'\nimport { USER_ROLE } from '../../users/constants/user'\nimport type { User } from '../../users/schemas/user.interface'\nimport { userFullNameSQL, users } from '../../users/schemas/users.schema'\nimport { CACHE_LINK_UUID_PREFIX, CACHE_LINK_UUID_TTL } from '../constants/cache'\nimport { LINK_TYPE } from '../constants/links'\nimport type { LinkAsUser, LinkGuest } from '../interfaces/link-guest.interface'\nimport type { SpaceLink } from '../interfaces/link-space.interface'\nimport type { Link } from '../schemas/link.interface'\nimport { links } from '../schemas/links.schema'\n\n@Injectable()\nexport class LinksQueries {\n constructor(\n @Inject(DB_TOKEN_PROVIDER) private readonly db: DBSchema,\n private readonly cache: Cache\n ) {}\n\n async linkFromShare(ownerId: number, linkId: number, shareId: number, isAdmin: number = 0): Promise<LinkGuest> {\n const [r] = await this.db\n .select({\n ...getTableColumns(links),\n permissions: sharesMembers.permissions,\n language: users.language,\n isActive: users.isActive\n })\n .from(links)\n .innerJoin(shares, and(eq(shares.id, shareId), or(eq(shares.ownerId, ownerId), and(eq(sql`${isAdmin}`, 1), isNull(shares.ownerId)))))\n .innerJoin(sharesMembers, and(eq(sharesMembers.shareId, shares.id), eq(sharesMembers.userId, links.userId), eq(sharesMembers.linkId, linkId)))\n .innerJoin(users, eq(users.id, links.userId))\n .where(eq(links.id, linkId))\n .limit(1)\n return r as LinkGuest\n }\n\n async linkFromSpace(managerId: number, linkId: number, spaceId: number): Promise<LinkGuest> {\n const linkMember: any = alias(spacesMembers, 'linkMember')\n const [r] = await this.db\n .select({\n ...getTableColumns(links),\n permissions: linkMember.permissions,\n language: users.language,\n isActive: users.isActive\n })\n .from(links)\n .innerJoin(\n spacesMembers,\n and(eq(spacesMembers.spaceId, spaceId), eq(spacesMembers.userId, managerId), eq(spacesMembers.role, SPACE_ROLE.IS_MANAGER))\n )\n .innerJoin(linkMember, and(eq(linkMember.spaceId, spacesMembers.spaceId), eq(linkMember.userId, links.userId), eq(linkMember.linkId, linkId)))\n .innerJoin(users, eq(users.id, links.userId))\n .where(eq(links.id, linkId))\n .limit(1)\n return r as LinkGuest\n }\n\n async updateLinkFromSpaceOrShare(\n link: LinkGuest,\n shareId: number,\n diffUser: Partial<User>,\n diffLink: Partial<Link>,\n diffShare: Partial<Share>,\n diffMember: Partial<ShareMembers>\n ) {\n if (Object.keys(diffUser).length) {\n await this.db.update(users).set(diffUser).where(eq(users.id, link.userId))\n }\n if (Object.keys(diffLink).length) {\n await this.db.update(links).set(diffLink).where(eq(links.id, link.id))\n }\n if (Object.keys(diffShare).length) {\n await this.db.update(shares).set(diffShare).where(eq(shares.id, shareId))\n }\n if (Object.keys(diffMember).length) {\n await this.db\n .update(sharesMembers)\n .set(diffMember)\n .where(and(eq(sharesMembers.shareId, shareId), eq(sharesMembers.userId, link.userId), eq(sharesMembers.linkId, link.id)))\n }\n }\n\n async createLinkToSpaceOrShare(guestId: number, spaceOrShareId: number, type: LINK_TYPE, link: Partial<LinkGuest>): Promise<number> {\n const linkId = dbGetInsertedId(await this.db.insert(links).values(link as Link))\n if (type === LINK_TYPE.SPACE) {\n await this.db.insert(spacesMembers).values({\n userId: guestId,\n spaceId: spaceOrShareId,\n permissions: link.permissions,\n role: SPACE_ROLE.IS_MEMBER,\n linkId: linkId\n } as SpaceMembers)\n } else {\n await this.db.insert(sharesMembers).values({\n userId: guestId,\n shareId: spaceOrShareId,\n linkId: linkId,\n permissions: link.permissions\n } as ShareMembers)\n }\n return linkId\n }\n\n allLinksFromSpaceOrShare(spaceOrShareId: number, type: LINK_TYPE): Promise<{ id: number; linkId: number }[]> {\n const members: any = alias(type == 'share' ? sharesMembers : spacesMembers, 'members')\n return this.db\n .select({ id: users.id, linkId: members.linkId })\n .from(members)\n .innerJoin(users, and(eq(users.id, members.userId), eq(users.role, USER_ROLE.LINK)))\n .where(and(eq(type == 'share' ? members.shareId : members.spaceId, spaceOrShareId), isNotNull(members.linkId)))\n }\n\n async linkFromUUID(uuid: string): Promise<LinkAsUser> {\n const { password, ...userColumns } = getTableColumns(users)\n const [r] = await this.db\n .select({\n ...getTableColumns(links),\n user: { ...userColumns }\n })\n .from(links)\n .leftJoin(users, eq(users.id, links.userId))\n .where(eq(links.uuid, uuid))\n .limit(1)\n return r\n }\n\n async spaceLink(uuid: string): Promise<SpaceLink> {\n const shareOwner: any = alias(users, 'shareOwner')\n const shareSpaceRoot: any = alias(spacesRoots, 'shareSpaceRoot')\n const [r]: SpaceLink[] = await this.db\n .select({\n share: {\n name: shares.name,\n alias: shares.alias,\n hasParent: isNotNull(shares.parentId).mapWith(Boolean),\n isDir: sql`IF (${isNotNull(shares.externalPath)}, 1 ,${files.isDir})`.mapWith(Boolean),\n mime: files.mime\n },\n space: { name: spaces.name, alias: spaces.alias },\n owner: { login: shareOwner.login, fullName: userFullNameSQL(shareOwner) }\n })\n .from(links)\n .leftJoin(sharesMembers, eq(sharesMembers.linkId, links.id))\n .leftJoin(shares, eq(shares.id, sharesMembers.shareId))\n .leftJoin(shareOwner, eq(shareOwner.id, shares.ownerId))\n .leftJoin(spacesMembers, eq(spacesMembers.linkId, links.id))\n .leftJoin(spaces, eq(spaces.id, spacesMembers.spaceId))\n .leftJoin(shareSpaceRoot, and(isNull(shares.externalPath), isNull(shares.fileId), eq(shareSpaceRoot.id, shares.spaceRootId)))\n .leftJoin(\n files,\n or(\n and(isNotNull(shares.fileId), eq(files.id, shares.fileId)),\n and(isNull(shares.externalPath), isNotNull(shareSpaceRoot.fileId), eq(files.id, shareSpaceRoot.fileId))\n )\n )\n .where(eq(links.uuid, uuid))\n .limit(1)\n return r\n }\n\n async incrementLinkNbAccess(uuid: string) {\n await this.db\n .update(links)\n .set({ nbAccess: sql`${links.nbAccess} + 1` } as Record<keyof Link, any>)\n .where(eq(links.uuid, uuid))\n .limit(1)\n }\n\n async isUniqueUUID(userId: number, uuid: string) {\n const [r] = await this.db.select({ check: links.uuid }).from(links).where(eq(links.uuid, uuid)).limit(1)\n if (!r) {\n // uuid does not exist in db\n const cacheKey = this.cache.genSlugKey(CACHE_LINK_UUID_PREFIX, userId, uuid)\n // check if uuid was already requested\n if (!(await this.cache.has(cacheKey))) {\n // store uuid to prevent reuse\n await this.cache.set(cacheKey, uuid, CACHE_LINK_UUID_TTL)\n return true\n }\n return false\n }\n return false\n }\n\n isReservedUUID(userId: number, uuid: string): Promise<boolean> {\n // check if uuid is reserved\n return this.cache.has(this.cache.genSlugKey(CACHE_LINK_UUID_PREFIX, userId, uuid))\n }\n}\n"],"names":["LinksQueries","linkFromShare","ownerId","linkId","shareId","isAdmin","r","db","select","getTableColumns","links","permissions","sharesMembers","language","users","isActive","from","innerJoin","shares","and","eq","id","or","sql","isNull","userId","where","limit","linkFromSpace","managerId","spaceId","linkMember","alias","spacesMembers","role","SPACE_ROLE","IS_MANAGER","updateLinkFromSpaceOrShare","link","diffUser","diffLink","diffShare","diffMember","Object","keys","length","update","set","createLinkToSpaceOrShare","guestId","spaceOrShareId","type","dbGetInsertedId","insert","values","LINK_TYPE","SPACE","IS_MEMBER","allLinksFromSpaceOrShare","members","USER_ROLE","LINK","isNotNull","linkFromUUID","uuid","password","userColumns","user","leftJoin","spaceLink","shareOwner","shareSpaceRoot","spacesRoots","share","name","hasParent","parentId","mapWith","Boolean","isDir","externalPath","files","mime","space","spaces","owner","login","fullName","userFullNameSQL","fileId","spaceRootId","incrementLinkNbAccess","nbAccess","isUniqueUUID","check","cacheKey","cache","genSlugKey","CACHE_LINK_UUID_PREFIX","has","CACHE_LINK_UUID_TTL","isReservedUUID"],"mappings":"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"}
|