@sync-in/server 1.7.0 → 1.8.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 +173 -58
- package/environment/environment.dist.yaml +6 -3
- package/migrations/0003_giant_luckman.sql +6 -0
- package/migrations/meta/0003_snapshot.json +2463 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +19 -17
- package/server/app.bootstrap.js +5 -2
- package/server/app.bootstrap.js.map +1 -1
- package/server/app.constants.js +0 -4
- package/server/app.constants.js.map +1 -1
- package/server/app.service.js +7 -6
- package/server/app.service.js.map +1 -1
- package/server/applications/files/constants/only-office.js +12 -0
- package/server/applications/files/constants/only-office.js.map +1 -1
- package/server/applications/files/files.config.js +5 -0
- package/server/applications/files/files.config.js.map +1 -1
- package/server/applications/files/files.controller.js +12 -4
- package/server/applications/files/files.controller.js.map +1 -1
- package/server/applications/files/files.controller.spec.js +18 -4
- package/server/applications/files/files.controller.spec.js.map +1 -1
- package/server/applications/files/services/files-content-manager.service.js +6 -6
- package/server/applications/files/services/files-content-manager.service.js.map +1 -1
- package/server/applications/files/services/files-manager.service.js +4 -4
- package/server/applications/files/services/files-manager.service.js.map +1 -1
- package/server/applications/files/services/files-methods.service.js +4 -7
- package/server/applications/files/services/files-methods.service.js.map +1 -1
- package/server/applications/files/services/files-only-office-manager.service.js +2 -2
- package/server/applications/files/services/files-only-office-manager.service.js.map +1 -1
- package/server/applications/files/services/files-parser.service.js +6 -3
- package/server/applications/files/services/files-parser.service.js.map +1 -1
- package/server/applications/files/services/files-scheduler.service.js +51 -3
- package/server/applications/files/services/files-scheduler.service.js.map +1 -1
- package/server/applications/files/services/files-search-manager.service.js +4 -0
- package/server/applications/files/services/files-search-manager.service.js.map +1 -1
- package/server/applications/files/utils/doc-textify/adapters/pdf.js +6 -8
- package/server/applications/files/utils/doc-textify/adapters/pdf.js.map +1 -1
- package/server/applications/notifications/i18n/de.js +56 -0
- package/server/applications/notifications/i18n/de.js.map +1 -0
- package/server/applications/notifications/i18n/es.js +52 -0
- package/server/applications/notifications/i18n/es.js.map +1 -0
- package/server/applications/notifications/i18n/hi.js +52 -0
- package/server/applications/notifications/i18n/hi.js.map +1 -0
- package/server/applications/notifications/i18n/index.js +73 -8
- package/server/applications/notifications/i18n/index.js.map +1 -1
- package/server/applications/notifications/i18n/it.js +52 -0
- package/server/applications/notifications/i18n/it.js.map +1 -0
- package/server/applications/notifications/i18n/ja.js +52 -0
- package/server/applications/notifications/i18n/ja.js.map +1 -0
- package/server/applications/notifications/i18n/ko.js +52 -0
- package/server/applications/notifications/i18n/ko.js.map +1 -0
- package/server/applications/notifications/i18n/pl.js +52 -0
- package/server/applications/notifications/i18n/pl.js.map +1 -0
- package/server/applications/notifications/i18n/pt.js +52 -0
- package/server/applications/notifications/i18n/pt.js.map +1 -0
- package/server/applications/notifications/i18n/pt_br.js +52 -0
- package/server/applications/notifications/i18n/pt_br.js.map +1 -0
- package/server/applications/notifications/i18n/ru.js +52 -0
- package/server/applications/notifications/i18n/ru.js.map +1 -0
- package/server/applications/notifications/i18n/tr.js +52 -0
- package/server/applications/notifications/i18n/tr.js.map +1 -0
- package/server/applications/notifications/i18n/zh.js +52 -0
- package/server/applications/notifications/i18n/zh.js.map +1 -0
- package/server/applications/notifications/mails/models.js +6 -7
- package/server/applications/notifications/mails/models.js.map +1 -1
- package/server/applications/notifications/services/notifications-manager.service.js.map +1 -1
- package/server/applications/shares/dto/create-or-update-share.dto.js +11 -0
- package/server/applications/shares/dto/create-or-update-share.dto.js.map +1 -1
- package/server/applications/shares/interfaces/share-props.interface.js.map +1 -1
- package/server/applications/shares/schemas/share.interface.js.map +1 -1
- package/server/applications/shares/schemas/shares.schema.js +9 -0
- package/server/applications/shares/schemas/shares.schema.js.map +1 -1
- package/server/applications/shares/services/shares-manager.service.js +46 -17
- package/server/applications/shares/services/shares-manager.service.js.map +1 -1
- package/server/applications/shares/services/shares-queries.service.js +24 -5
- package/server/applications/shares/services/shares-queries.service.js.map +1 -1
- package/server/applications/spaces/constants/cache.js +4 -0
- package/server/applications/spaces/constants/cache.js.map +1 -1
- package/server/applications/spaces/dto/create-or-update-space.dto.js +5 -0
- package/server/applications/spaces/dto/create-or-update-space.dto.js.map +1 -1
- package/server/applications/spaces/guards/space.guard.js +3 -3
- package/server/applications/spaces/guards/space.guard.js.map +1 -1
- package/server/applications/spaces/models/space-props.model.js.map +1 -1
- package/server/applications/spaces/models/space.model.js.map +1 -1
- package/server/applications/spaces/schemas/space.interface.js.map +1 -1
- package/server/applications/spaces/schemas/spaces.schema.js +1 -0
- package/server/applications/spaces/schemas/spaces.schema.js.map +1 -1
- package/server/applications/spaces/services/spaces-browser.service.js.map +1 -1
- package/server/applications/spaces/services/spaces-manager.service.js +34 -31
- package/server/applications/spaces/services/spaces-manager.service.js.map +1 -1
- package/server/applications/spaces/services/spaces-queries.service.js +23 -7
- package/server/applications/spaces/services/spaces-queries.service.js.map +1 -1
- package/server/applications/spaces/services/spaces-scheduler.service.js +21 -20
- package/server/applications/spaces/services/spaces-scheduler.service.js.map +1 -1
- package/server/applications/spaces/spaces.controller.js +4 -2
- package/server/applications/spaces/spaces.controller.js.map +1 -1
- package/server/applications/spaces/utils/paths.js +14 -16
- package/server/applications/spaces/utils/paths.js.map +1 -1
- package/server/applications/sync/services/sync-manager.service.js +4 -3
- package/server/applications/sync/services/sync-manager.service.js.map +1 -1
- package/server/applications/sync/services/sync-paths-manager.service.js +1 -1
- package/server/applications/sync/services/sync-paths-manager.service.js.map +1 -1
- package/server/applications/sync/services/sync-paths-manager.service.spec.js +1 -1
- package/server/applications/sync/services/sync-paths-manager.service.spec.js.map +1 -1
- package/server/applications/sync/sync.controller.js +2 -1
- package/server/applications/sync/sync.controller.js.map +1 -1
- package/server/applications/users/constants/routes.js +5 -0
- package/server/applications/users/constants/routes.js.map +1 -1
- package/server/applications/users/constants/user.js +0 -16
- package/server/applications/users/constants/user.js.map +1 -1
- package/server/applications/users/dto/user-properties.dto.js +10 -0
- package/server/applications/users/dto/user-properties.dto.js.map +1 -1
- package/server/applications/users/models/user.model.js.map +1 -1
- package/server/applications/users/schemas/user.interface.js.map +1 -1
- package/server/applications/users/schemas/users.schema.js +3 -2
- package/server/applications/users/schemas/users.schema.js.map +1 -1
- package/server/applications/users/services/admin-users-manager.service.js +1 -0
- package/server/applications/users/services/admin-users-manager.service.js.map +1 -1
- package/server/applications/users/services/admin-users-manager.service.spec.js +2 -1
- package/server/applications/users/services/admin-users-manager.service.spec.js.map +1 -1
- package/server/applications/users/services/users-manager.service.js +7 -2
- package/server/applications/users/services/users-manager.service.js.map +1 -1
- package/server/applications/users/services/users-manager.service.spec.js +1 -0
- package/server/applications/users/services/users-manager.service.spec.js.map +1 -1
- package/server/applications/users/services/users-queries.service.js +18 -4
- package/server/applications/users/services/users-queries.service.js.map +1 -1
- package/server/applications/users/users.controller.js +15 -0
- package/server/applications/users/users.controller.js.map +1 -1
- package/server/applications/users/users.gateway.js +6 -0
- package/server/applications/users/users.gateway.js.map +1 -1
- package/server/applications/users/utils/test.js +2 -2
- package/server/applications/users/utils/test.js.map +1 -1
- package/server/applications/webdav/constants/routes.js +2 -2
- package/server/applications/webdav/constants/routes.js.map +1 -1
- package/server/applications/webdav/constants/webdav.js +2 -2
- package/server/applications/webdav/constants/webdav.js.map +1 -1
- package/server/applications/webdav/filters/webdav.filter.js +2 -2
- package/server/applications/webdav/filters/webdav.filter.js.map +1 -1
- package/server/applications/webdav/filters/webdav.filter.spec.js +2 -2
- package/server/applications/webdav/filters/webdav.filter.spec.js.map +1 -1
- package/server/applications/webdav/services/webdav-methods.service.js +3 -2
- package/server/applications/webdav/services/webdav-methods.service.js.map +1 -1
- package/server/applications/webdav/utils/webdav.js +1 -2
- package/server/applications/webdav/utils/webdav.js.map +1 -1
- package/server/authentication/auth.config.js +2 -2
- package/server/authentication/auth.config.js.map +1 -1
- package/server/authentication/guards/auth-basic.strategy.js +2 -2
- package/server/authentication/guards/auth-basic.strategy.js.map +1 -1
- package/server/common/i18n.js +52 -0
- package/server/common/i18n.js.map +1 -0
- package/server/common/image.js +63 -43
- package/server/common/image.js.map +1 -1
- package/server/common/interfaces.js.map +1 -1
- package/server/common/shared.js +5 -2
- package/server/common/shared.js.map +1 -1
- package/server/configuration/config.validation.js +3 -3
- package/server/configuration/config.validation.js.map +1 -1
- package/server/infrastructure/cache/adapters/mysql-cache.adapter.js +8 -6
- package/server/infrastructure/cache/adapters/mysql-cache.adapter.js.map +1 -1
- package/server/infrastructure/cache/adapters/redis-cache.adapter.js +22 -17
- package/server/infrastructure/cache/adapters/redis-cache.adapter.js.map +1 -1
- package/server/infrastructure/cache/cache.e2e-spec.js +1 -0
- package/server/infrastructure/cache/cache.e2e-spec.js.map +1 -1
- package/server/infrastructure/cache/cache.module.js +1 -14
- package/server/infrastructure/cache/cache.module.js.map +1 -1
- package/server/infrastructure/cache/services/cache.service.js.map +1 -1
- package/server/infrastructure/database/database.module.js +20 -1
- package/server/infrastructure/database/database.module.js.map +1 -1
- package/server/infrastructure/database/utils.js +48 -0
- package/server/infrastructure/database/utils.js.map +1 -1
- package/server/infrastructure/scheduler/scheduler.module.js +1 -1
- package/server/infrastructure/scheduler/scheduler.module.js.map +1 -1
- package/server/infrastructure/websocket/adapters/cluster.adapter.js +1 -3
- package/server/infrastructure/websocket/adapters/cluster.adapter.js.map +1 -1
- package/static/3rdpartylicenses.txt +137 -163
- package/static/chunk-2KLC4T2Z.js +1 -0
- package/static/chunk-2VMSXRCB.js +12 -0
- package/static/chunk-3GMLWAFZ.js +1 -0
- package/static/chunk-3OHSRRKH.js +4 -0
- package/static/chunk-3R4WKOHQ.js +1 -0
- package/static/{chunk-7ITZXYYJ.js → chunk-3R74L4UU.js} +1 -1
- package/static/chunk-3XVM35O2.js +1 -0
- package/static/chunk-3YVRP3VM.js +2 -0
- package/static/chunk-5NMSIIQB.js +1 -0
- package/static/chunk-5UKZLU5H.js +1 -0
- package/static/chunk-AF24EYXU.js +1 -0
- package/static/chunk-AKQVEHO6.js +2 -0
- package/static/chunk-BCVX464U.js +2 -0
- package/static/chunk-BQV4FRM6.js +1 -0
- package/static/{chunk-EVIE5F2U.js → chunk-CETH7UYS.js} +1 -1
- package/static/chunk-CHJ64RJM.js +1 -0
- package/static/chunk-DIT6W7VM.js +562 -0
- package/static/chunk-DKSEQTMX.js +1 -0
- package/static/chunk-DM4NXKEP.js +1 -0
- package/static/chunk-DPUVSXRB.js +1 -0
- package/static/chunk-DSWEWLXJ.js +1 -0
- package/static/chunk-FJE6BOFL.js +1 -0
- package/static/chunk-FZ3JPGYZ.js +1 -0
- package/static/chunk-IQSKQXC3.js +1 -0
- package/static/chunk-ITUFI2BJ.js +1 -0
- package/static/chunk-JPT5WEAT.js +1 -0
- package/static/chunk-LCTZJ537.js +1 -0
- package/static/chunk-LK2UCQJ6.js +1 -0
- package/static/chunk-LNTUR3GU.js +1 -0
- package/static/chunk-LP5TBXEN.js +7 -0
- package/static/{chunk-IPAC4VAF.js → chunk-LVSNIS5P.js} +1 -1
- package/static/{chunk-SIPE37PA.js → chunk-MTVSJTIW.js} +1 -1
- package/static/chunk-N3U6637P.js +1 -0
- package/static/chunk-NNV4OXSB.js +1 -0
- package/static/chunk-O6FYXVHI.js +1 -0
- package/static/chunk-OOGP4WSH.js +2 -0
- package/static/chunk-PB4AIT7O.js +1 -0
- package/static/chunk-PCWDQPOM.js +2 -0
- package/static/chunk-PNR6M34W.js +1 -0
- package/static/chunk-PVDHBQRM.js +1 -0
- package/static/chunk-Q5KM7LTX.js +1 -0
- package/static/chunk-QHC6ZPQ4.js +1 -0
- package/static/chunk-QMRBZHE4.js +1 -0
- package/static/chunk-QO6BTONN.js +1 -0
- package/static/chunk-QSJRY3TF.js +1 -0
- package/static/chunk-QUUIRSYT.js +1 -0
- package/static/chunk-RFH46UW3.js +1 -0
- package/static/{chunk-PTGDOWV3.js → chunk-RSXHRKM5.js} +1 -1
- package/static/chunk-RV3VZJPZ.js +1 -0
- package/static/{chunk-QNJFQVYI.js → chunk-S7HNXVRB.js} +1 -1
- package/static/chunk-SBZ572Q4.js +2 -0
- package/static/chunk-SJR5R3Y4.js +1 -0
- package/static/chunk-SLHTEGRU.js +1 -0
- package/static/{chunk-SH5EVL4E.js → chunk-SSFF27P2.js} +1 -1
- package/static/chunk-UNCPXHHT.js +1 -0
- package/static/chunk-URHTCJ7G.js +1 -0
- package/static/chunk-V3LHHZYN.js +1 -0
- package/static/{chunk-DJYJ66UF.js → chunk-VJTXJ43D.js} +1 -1
- package/static/chunk-VQQKMY2C.js +1 -0
- package/static/{chunk-IQOALFYU.js → chunk-WSSU2HXE.js} +1 -1
- package/static/chunk-XDZGW64M.js +3 -0
- package/static/chunk-XTRDKGKG.js +1 -0
- package/static/chunk-YLWTEC3X.js +1 -0
- package/static/chunk-Z5J5F5SX.js +1 -0
- package/static/chunk-ZIJQRARU.js +1 -0
- package/static/index.html +2 -2
- package/static/main-4H5BJY3J.js +9 -0
- package/static/scripts-WRDOQIU5.js +24 -0
- package/static/{styles-A5VYX3CE.css → styles-2C2UNCNB.css} +1 -1
- package/server/applications/spaces/interfaces/space-quota.interface.js +0 -10
- package/server/applications/spaces/interfaces/space-quota.interface.js.map +0 -1
- package/static/chunk-22EANI6R.js +0 -1
- package/static/chunk-3GFGJYMK.js +0 -1
- package/static/chunk-4YGJGZZZ.js +0 -1
- package/static/chunk-5K7HEX3C.js +0 -27
- package/static/chunk-5KLMS6A4.js +0 -1
- package/static/chunk-ATP3BFHV.js +0 -562
- package/static/chunk-BB4G55KE.js +0 -1
- package/static/chunk-EWKSX76T.js +0 -1
- package/static/chunk-FHLACA7V.js +0 -1
- package/static/chunk-GCATNU55.js +0 -1
- package/static/chunk-GYODPCIE.js +0 -1
- package/static/chunk-HZTFYLM5.js +0 -1
- package/static/chunk-JSUKJT6Z.js +0 -1
- package/static/chunk-JXZCNFW7.js +0 -1
- package/static/chunk-LTGFCQR7.js +0 -1
- package/static/chunk-LV3PYKWO.js +0 -1
- package/static/chunk-N2WFNW6M.js +0 -7
- package/static/chunk-ORMRCEGT.js +0 -1
- package/static/chunk-OUTBJSMW.js +0 -1
- package/static/chunk-RS2PX32L.js +0 -1
- package/static/chunk-RSSWH3S2.js +0 -1
- package/static/chunk-RTRJ3KFH.js +0 -1
- package/static/chunk-TKTCBDOG.js +0 -1
- package/static/chunk-V6K2N46L.js +0 -1
- package/static/chunk-XLCCZSQL.js +0 -4
- package/static/chunk-YPEH66GG.js +0 -1
- package/static/chunk-YPOIUQ57.js +0 -1
- package/static/chunk-ZKCFO2OA.js +0 -4
- package/static/main-MZ7HWZXO.js +0 -9
- package/static/scripts-VZVAP2P4.js +0 -30
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/webdav/constants/webdav.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 { SERVER_NAME } from '../../../
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/webdav/constants/webdav.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 { SERVER_NAME } from '../../../common/shared'\nimport { HTTP_STANDARD_METHOD, HTTP_WEBDAV_METHOD } from '../../applications.constants'\nimport { WEBDAV_BASE_PATH } from './routes'\n\nexport const REGEX_BASE_PATH = new RegExp(`^/?${WEBDAV_BASE_PATH}/`)\nexport const NS_DAV = 'DAV:'\nexport const NS_PREFIX = 'D'\nexport const LOCK_PREFIX = 'urn:uuid:'\nexport const XML_CONTENT_TYPE = 'application/xml; charset=utf-8'\nexport const HTML_CONTENT_TYPE = 'text/html; charset=utf-8'\n\nexport const ALLOWED_WEBDAV_METHODS: string = [\n HTTP_STANDARD_METHOD.OPTIONS,\n HTTP_STANDARD_METHOD.HEAD,\n HTTP_STANDARD_METHOD.GET,\n HTTP_STANDARD_METHOD.PUT,\n HTTP_STANDARD_METHOD.DELETE,\n ...Object.values(HTTP_WEBDAV_METHOD)\n].join(', ')\n\nexport const ALLOW_EMPTY_BODY_METHODS: string[] = [HTTP_WEBDAV_METHOD.PROPFIND, HTTP_WEBDAV_METHOD.LOCK]\n\nexport const OPTIONS_HEADERS = {\n Server: SERVER_NAME,\n 'MS-Author-Via': 'DAV',\n DAV: '1,2',\n Allow: ALLOWED_WEBDAV_METHODS,\n 'Content-Type': HTML_CONTENT_TYPE,\n 'Content-Length': '0',\n 'Accept-Ranges': 'bytes'\n} as const\n\nexport const HEADER = {\n DEPTH: 'depth',\n IF: 'if',\n LOCK_TOKEN: 'lock-token',\n DESTINATION: 'destination',\n OVERWRITE: 'overwrite',\n TIMEOUT: 'timeout'\n} as const\n\nexport const LOCK_DISCOVERY_PROP = 'lockdiscovery'\nexport const STANDARD_PROPS = [\n 'creationdate',\n 'getcontenttype',\n 'resourcetype',\n 'getlastmodified',\n 'getcontentlength',\n 'displayname',\n 'getetag',\n 'supportedlock',\n LOCK_DISCOVERY_PROP\n]\n\nexport enum LOCK_SCOPE {\n EXCLUSIVE = 'exclusive',\n SHARED = 'shared'\n}\n\nexport enum DEPTH {\n INFINITY = 'infinity',\n RESOURCE = '0',\n MEMBERS = '1'\n}\n\nexport type LOCK_DEPTH = Omit<DEPTH, DEPTH.MEMBERS>\n\nexport enum PROPSTAT {\n ALLPROP = 'allprop',\n PROP = 'prop',\n PROPNAME = 'propname'\n}\n\nexport const PROPPATCH_PROP_UPDATE = 'propertyupdate'\nexport const PROPPATCH_METHOD = { SET: 'set', REMOVE: 'remove' }\nexport const PROPPATCH_MODIFIED_PROPS = ['getlastmodified', 'lastmodified', 'Win32LastModifiedTime']\nexport const PROPPATCH_SUPPORTED_PROPS = [...PROPPATCH_MODIFIED_PROPS, 'Win32CreationTime', 'Win32LastAccessTime', 'Win32FileAttributes']\n\nexport const PRECONDITION = {\n PROTECTED_PROPERTY: 'cannot-modify-protected-property',\n MISSING_LOCK_TOKEN: 'lock-token-submitted',\n LOCK_TOKEN_MISMATCH: 'lock-token-matches-request-uri',\n LOCK_CONFLICT: 'no-conflicting-lock',\n PROPFIND_FINITE_DEPTH: 'propfind-finite-depth'\n} as const\n"],"names":["ALLOWED_WEBDAV_METHODS","ALLOW_EMPTY_BODY_METHODS","DEPTH","HEADER","HTML_CONTENT_TYPE","LOCK_DISCOVERY_PROP","LOCK_PREFIX","LOCK_SCOPE","NS_DAV","NS_PREFIX","OPTIONS_HEADERS","PRECONDITION","PROPPATCH_METHOD","PROPPATCH_MODIFIED_PROPS","PROPPATCH_PROP_UPDATE","PROPPATCH_SUPPORTED_PROPS","PROPSTAT","REGEX_BASE_PATH","STANDARD_PROPS","XML_CONTENT_TYPE","RegExp","WEBDAV_BASE_PATH","HTTP_STANDARD_METHOD","OPTIONS","HEAD","GET","PUT","DELETE","Object","values","HTTP_WEBDAV_METHOD","join","PROPFIND","LOCK","Server","SERVER_NAME","DAV","Allow","IF","LOCK_TOKEN","DESTINATION","OVERWRITE","TIMEOUT","SET","REMOVE","PROTECTED_PROPERTY","MISSING_LOCK_TOKEN","LOCK_TOKEN_MISMATCH","LOCK_CONFLICT","PROPFIND_FINITE_DEPTH"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAaYA;eAAAA;;QASAC;eAAAA;;QAuCDC;eAAAA;;QA3BCC;eAAAA;;QAvBAC;eAAAA;;QAgCAC;eAAAA;;QAlCAC;eAAAA;;QA+CDC;eAAAA;;QAjDCC;eAAAA;;QACAC;eAAAA;;QAgBAC;eAAAA;;QAwDAC;eAAAA;;QAJAC;eAAAA;;QACAC;eAAAA;;QAFAC;eAAAA;;QAGAC;eAAAA;;QATDC;eAAAA;;QA/DCC;eAAAA;;QAsCAC;eAAAA;;QAlCAC;eAAAA;;;wBARe;uCAC6B;wBACxB;AAE1B,MAAMF,kBAAkB,IAAIG,OAAO,CAAC,GAAG,EAAEC,wBAAgB,CAAC,CAAC,CAAC;AAC5D,MAAMb,SAAS;AACf,MAAMC,YAAY;AAClB,MAAMH,cAAc;AACpB,MAAMa,mBAAmB;AACzB,MAAMf,oBAAoB;AAE1B,MAAMJ,yBAAiC;IAC5CsB,2CAAoB,CAACC,OAAO;IAC5BD,2CAAoB,CAACE,IAAI;IACzBF,2CAAoB,CAACG,GAAG;IACxBH,2CAAoB,CAACI,GAAG;IACxBJ,2CAAoB,CAACK,MAAM;OACxBC,OAAOC,MAAM,CAACC,yCAAkB;CACpC,CAACC,IAAI,CAAC;AAEA,MAAM9B,2BAAqC;IAAC6B,yCAAkB,CAACE,QAAQ;IAAEF,yCAAkB,CAACG,IAAI;CAAC;AAEjG,MAAMvB,kBAAkB;IAC7BwB,QAAQC,mBAAW;IACnB,iBAAiB;IACjBC,KAAK;IACLC,OAAOrC;IACP,gBAAgBI;IAChB,kBAAkB;IAClB,iBAAiB;AACnB;AAEO,MAAMD,SAAS;IACpBD,OAAO;IACPoC,IAAI;IACJC,YAAY;IACZC,aAAa;IACbC,WAAW;IACXC,SAAS;AACX;AAEO,MAAMrC,sBAAsB;AAC5B,MAAMa,iBAAiB;IAC5B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACAb;CACD;AAEM,IAAA,AAAKE,oCAAAA;;;WAAAA;;AAKL,IAAA,AAAKL,+BAAAA;;;;WAAAA;;AAQL,IAAA,AAAKc,kCAAAA;;;;WAAAA;;AAML,MAAMF,wBAAwB;AAC9B,MAAMF,mBAAmB;IAAE+B,KAAK;IAAOC,QAAQ;AAAS;AACxD,MAAM/B,2BAA2B;IAAC;IAAmB;IAAgB;CAAwB;AAC7F,MAAME,4BAA4B;OAAIF;IAA0B;IAAqB;IAAuB;CAAsB;AAElI,MAAMF,eAAe;IAC1BkC,oBAAoB;IACpBC,oBAAoB;IACpBC,qBAAqB;IACrBC,eAAe;IACfC,uBAAuB;AACzB"}
|
|
@@ -13,7 +13,7 @@ Object.defineProperty(exports, "WebDAVExceptionsFilter", {
|
|
|
13
13
|
}
|
|
14
14
|
});
|
|
15
15
|
const _common = require("@nestjs/common");
|
|
16
|
-
const
|
|
16
|
+
const _shared = require("../../../common/shared");
|
|
17
17
|
const _webdav = require("../constants/webdav");
|
|
18
18
|
function _ts_decorate(decorators, target, key, desc) {
|
|
19
19
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -28,7 +28,7 @@ let WebDAVExceptionsFilter = class WebDAVExceptionsFilter {
|
|
|
28
28
|
const status = exception.getStatus();
|
|
29
29
|
if (status === 401) {
|
|
30
30
|
// req.authInfo from the AuthBasicGuard
|
|
31
|
-
res.header('WWW-Authenticate', `Basic realm="${
|
|
31
|
+
res.header('WWW-Authenticate', `Basic realm="${_shared.SERVER_NAME}"`).status(status).send();
|
|
32
32
|
} else {
|
|
33
33
|
let response = exception.getResponse();
|
|
34
34
|
if (typeof response === 'object' && response !== null) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/webdav/filters/webdav.filter.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 { ArgumentsHost, Catch, ExceptionFilter, HttpException } from '@nestjs/common'\nimport { SERVER_NAME } from '../../../
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/webdav/filters/webdav.filter.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 { ArgumentsHost, Catch, ExceptionFilter, HttpException } from '@nestjs/common'\nimport { SERVER_NAME } from '../../../common/shared'\nimport { XML_CONTENT_TYPE } from '../constants/webdav'\n\n@Catch(HttpException)\nexport class WebDAVExceptionsFilter implements ExceptionFilter {\n catch(exception: HttpException, host: ArgumentsHost) {\n const ctx = host.switchToHttp()\n const res = ctx.getResponse()\n const status = exception.getStatus()\n\n if (status === 401) {\n // req.authInfo from the AuthBasicGuard\n res.header('WWW-Authenticate', `Basic realm=\"${SERVER_NAME}\"`).status(status).send()\n } else {\n let response: any = exception.getResponse()\n if (typeof response === 'object' && response !== null) {\n response = response.message\n }\n res.type(XML_CONTENT_TYPE).status(status).send(response)\n }\n }\n}\n"],"names":["WebDAVExceptionsFilter","catch","exception","host","ctx","switchToHttp","res","getResponse","status","getStatus","header","SERVER_NAME","send","response","message","type","XML_CONTENT_TYPE"],"mappings":"AAAA;;;;CAIC;;;;+BAOYA;;;eAAAA;;;wBALwD;wBACzC;wBACK;;;;;;;AAG1B,IAAA,AAAMA,yBAAN,MAAMA;IACXC,MAAMC,SAAwB,EAAEC,IAAmB,EAAE;QACnD,MAAMC,MAAMD,KAAKE,YAAY;QAC7B,MAAMC,MAAMF,IAAIG,WAAW;QAC3B,MAAMC,SAASN,UAAUO,SAAS;QAElC,IAAID,WAAW,KAAK;YAClB,uCAAuC;YACvCF,IAAII,MAAM,CAAC,oBAAoB,CAAC,aAAa,EAAEC,mBAAW,CAAC,CAAC,CAAC,EAAEH,MAAM,CAACA,QAAQI,IAAI;QACpF,OAAO;YACL,IAAIC,WAAgBX,UAAUK,WAAW;YACzC,IAAI,OAAOM,aAAa,YAAYA,aAAa,MAAM;gBACrDA,WAAWA,SAASC,OAAO;YAC7B;YACAR,IAAIS,IAAI,CAACC,wBAAgB,EAAER,MAAM,CAACA,QAAQI,IAAI,CAACC;QACjD;IACF;AACF"}
|
|
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
8
8
|
});
|
|
9
9
|
const _common = require("@nestjs/common");
|
|
10
10
|
const _testing = require("@nestjs/testing");
|
|
11
|
-
const
|
|
11
|
+
const _shared = require("../../../common/shared");
|
|
12
12
|
const _webdav = require("../constants/webdav");
|
|
13
13
|
const _webdavfilter = require("./webdav.filter");
|
|
14
14
|
describe('WebDAVExceptionsFilter', ()=>{
|
|
@@ -42,7 +42,7 @@ describe('WebDAVExceptionsFilter', ()=>{
|
|
|
42
42
|
const host = createMockHost(res);
|
|
43
43
|
const exception = new _common.HttpException('Unauthorized', 401);
|
|
44
44
|
filter.catch(exception, host);
|
|
45
|
-
expect(res.header).toHaveBeenCalledWith('WWW-Authenticate', `Basic realm="${
|
|
45
|
+
expect(res.header).toHaveBeenCalledWith('WWW-Authenticate', `Basic realm="${_shared.SERVER_NAME}"`);
|
|
46
46
|
expect(res.status).toHaveBeenCalledWith(401);
|
|
47
47
|
expect(res.type).not.toHaveBeenCalled();
|
|
48
48
|
expect(res.send).toHaveBeenCalled();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/webdav/filters/webdav.filter.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 */\nimport { ArgumentsHost, HttpException } from '@nestjs/common'\nimport { Test } from '@nestjs/testing'\nimport { SERVER_NAME } from '../../../
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/webdav/filters/webdav.filter.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 */\nimport { ArgumentsHost, HttpException } from '@nestjs/common'\nimport { Test } from '@nestjs/testing'\nimport { SERVER_NAME } from '../../../common/shared'\nimport { XML_CONTENT_TYPE } from '../constants/webdav'\nimport { WebDAVExceptionsFilter } from './webdav.filter'\n\ndescribe('WebDAVExceptionsFilter', () => {\n let filter: WebDAVExceptionsFilter\n\n const createMockResponse = () => {\n const res: any = {}\n res.header = jest.fn().mockReturnValue(res)\n res.type = jest.fn().mockReturnValue(res)\n res.status = jest.fn().mockReturnValue(res)\n res.send = jest.fn().mockReturnValue(res)\n return res\n }\n\n const createMockHost = (res: any): ArgumentsHost =>\n ({\n switchToHttp: () => ({\n getResponse: () => res\n })\n // Other methods not used by the filter\n }) as unknown as ArgumentsHost\n\n beforeEach(async () => {\n const moduleRef = await Test.createTestingModule({\n providers: [WebDAVExceptionsFilter]\n }).compile()\n\n filter = moduleRef.get(WebDAVExceptionsFilter)\n })\n\n afterEach(() => {\n jest.clearAllMocks()\n })\n\n it('should set WWW-Authenticate header and send empty body for 401', () => {\n const res = createMockResponse()\n const host = createMockHost(res)\n const exception = new HttpException('Unauthorized', 401)\n\n filter.catch(exception, host)\n\n expect(res.header).toHaveBeenCalledWith('WWW-Authenticate', `Basic realm=\"${SERVER_NAME}\"`)\n expect(res.status).toHaveBeenCalledWith(401)\n expect(res.type).not.toHaveBeenCalled()\n expect(res.send).toHaveBeenCalled()\n // Ensure no body is sent\n expect(res.send.mock.calls[0][0]).toBeUndefined()\n })\n\n it('should set XML content type and forward string response for non-401', () => {\n const res = createMockResponse()\n const host = createMockHost(res)\n const exception = new HttpException('Internal error', 500)\n\n filter.catch(exception, host)\n\n expect(res.type).toHaveBeenCalledWith(XML_CONTENT_TYPE)\n expect(res.status).toHaveBeenCalledWith(500)\n expect(res.send).toHaveBeenCalledWith('Internal error')\n expect(res.header).not.toHaveBeenCalled()\n })\n\n it('should extract \"message\" from object response and send it as XML for non-401', () => {\n const res = createMockResponse()\n const host = createMockHost(res)\n const payload = { message: '<error>Bad Request</error>' }\n const exception = new HttpException(payload, 400)\n\n filter.catch(exception, host)\n\n expect(res.type).toHaveBeenCalledWith(XML_CONTENT_TYPE)\n expect(res.status).toHaveBeenCalledWith(400)\n expect(res.send).toHaveBeenCalledWith(payload.message)\n expect(res.header).not.toHaveBeenCalled()\n })\n})\n"],"names":["describe","filter","createMockResponse","res","header","jest","fn","mockReturnValue","type","status","send","createMockHost","switchToHttp","getResponse","beforeEach","moduleRef","Test","createTestingModule","providers","WebDAVExceptionsFilter","compile","get","afterEach","clearAllMocks","it","host","exception","HttpException","catch","expect","toHaveBeenCalledWith","SERVER_NAME","not","toHaveBeenCalled","mock","calls","toBeUndefined","XML_CONTENT_TYPE","payload","message"],"mappings":"AAAA;;;;CAIC;;;;wBAC4C;yBACxB;wBACO;wBACK;8BACM;AAEvCA,SAAS,0BAA0B;IACjC,IAAIC;IAEJ,MAAMC,qBAAqB;QACzB,MAAMC,MAAW,CAAC;QAClBA,IAAIC,MAAM,GAAGC,KAAKC,EAAE,GAAGC,eAAe,CAACJ;QACvCA,IAAIK,IAAI,GAAGH,KAAKC,EAAE,GAAGC,eAAe,CAACJ;QACrCA,IAAIM,MAAM,GAAGJ,KAAKC,EAAE,GAAGC,eAAe,CAACJ;QACvCA,IAAIO,IAAI,GAAGL,KAAKC,EAAE,GAAGC,eAAe,CAACJ;QACrC,OAAOA;IACT;IAEA,MAAMQ,iBAAiB,CAACR,MACrB,CAAA;YACCS,cAAc,IAAO,CAAA;oBACnBC,aAAa,IAAMV;gBACrB,CAAA;QAEF,CAAA;IAEFW,WAAW;QACT,MAAMC,YAAY,MAAMC,aAAI,CAACC,mBAAmB,CAAC;YAC/CC,WAAW;gBAACC,oCAAsB;aAAC;QACrC,GAAGC,OAAO;QAEVnB,SAASc,UAAUM,GAAG,CAACF,oCAAsB;IAC/C;IAEAG,UAAU;QACRjB,KAAKkB,aAAa;IACpB;IAEAC,GAAG,kEAAkE;QACnE,MAAMrB,MAAMD;QACZ,MAAMuB,OAAOd,eAAeR;QAC5B,MAAMuB,YAAY,IAAIC,qBAAa,CAAC,gBAAgB;QAEpD1B,OAAO2B,KAAK,CAACF,WAAWD;QAExBI,OAAO1B,IAAIC,MAAM,EAAE0B,oBAAoB,CAAC,oBAAoB,CAAC,aAAa,EAAEC,mBAAW,CAAC,CAAC,CAAC;QAC1FF,OAAO1B,IAAIM,MAAM,EAAEqB,oBAAoB,CAAC;QACxCD,OAAO1B,IAAIK,IAAI,EAAEwB,GAAG,CAACC,gBAAgB;QACrCJ,OAAO1B,IAAIO,IAAI,EAAEuB,gBAAgB;QACjC,yBAAyB;QACzBJ,OAAO1B,IAAIO,IAAI,CAACwB,IAAI,CAACC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAEC,aAAa;IACjD;IAEAZ,GAAG,uEAAuE;QACxE,MAAMrB,MAAMD;QACZ,MAAMuB,OAAOd,eAAeR;QAC5B,MAAMuB,YAAY,IAAIC,qBAAa,CAAC,kBAAkB;QAEtD1B,OAAO2B,KAAK,CAACF,WAAWD;QAExBI,OAAO1B,IAAIK,IAAI,EAAEsB,oBAAoB,CAACO,wBAAgB;QACtDR,OAAO1B,IAAIM,MAAM,EAAEqB,oBAAoB,CAAC;QACxCD,OAAO1B,IAAIO,IAAI,EAAEoB,oBAAoB,CAAC;QACtCD,OAAO1B,IAAIC,MAAM,EAAE4B,GAAG,CAACC,gBAAgB;IACzC;IAEAT,GAAG,gFAAgF;QACjF,MAAMrB,MAAMD;QACZ,MAAMuB,OAAOd,eAAeR;QAC5B,MAAMmC,UAAU;YAAEC,SAAS;QAA6B;QACxD,MAAMb,YAAY,IAAIC,qBAAa,CAACW,SAAS;QAE7CrC,OAAO2B,KAAK,CAACF,WAAWD;QAExBI,OAAO1B,IAAIK,IAAI,EAAEsB,oBAAoB,CAACO,wBAAgB;QACtDR,OAAO1B,IAAIM,MAAM,EAAEqB,oBAAoB,CAAC;QACxCD,OAAO1B,IAAIO,IAAI,EAAEoB,oBAAoB,CAACQ,QAAQC,OAAO;QACrDV,OAAO1B,IAAIC,MAAM,EAAE4B,GAAG,CAACC,gBAAgB;IACzC;AACF"}
|
|
@@ -420,12 +420,13 @@ let WebDAVMethods = class WebDAVMethods {
|
|
|
420
420
|
}
|
|
421
421
|
handleError(req, res, e, toUrl) {
|
|
422
422
|
this.logger.error(`Unable to ${req.method} ${req.dav.url}${toUrl ? ` -> ${toUrl}` : ''} : ${e.message}`);
|
|
423
|
+
const errorMsg = e.message.split(',')[0];
|
|
423
424
|
if (e instanceof _filelockerror.LockConflict) {
|
|
424
425
|
return (0, _webdav1.DAV_ERROR_RES)(_common.HttpStatus.LOCKED, _webdav.PRECONDITION.LOCK_CONFLICT, res, e.lock.davLock?.lockroot || e.lock.dbFilePath);
|
|
425
426
|
} else if (e instanceof _fileerror.FileError) {
|
|
426
|
-
return res.status(e.httpCode).send(
|
|
427
|
+
return res.status(e.httpCode).send(errorMsg);
|
|
427
428
|
}
|
|
428
|
-
throw new _common.HttpException(
|
|
429
|
+
throw new _common.HttpException(errorMsg, _common.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
429
430
|
}
|
|
430
431
|
constructor(webDAVHandler, filesManager, filesLockManager){
|
|
431
432
|
this.webDAVHandler = webDAVHandler;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/webdav/services/webdav-methods.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 } from 'fastify'\nimport { currentTimeStamp, encodeUrl } from '../../../common/shared'\nimport { FileLock } from '../../files/interfaces/file-lock.interface'\nimport { FileError } from '../../files/models/file-error'\nimport { LockConflict } from '../../files/models/file-lock-error'\nimport { FilesLockManager } from '../../files/services/files-lock-manager.service'\nimport { FilesManager } from '../../files/services/files-manager.service'\nimport { dirName, genEtag, isPathExists } from '../../files/utils/files'\nimport { SPACE_OPERATION, SPACE_REPOSITORY } from '../../spaces/constants/spaces'\nimport { SpaceEnv } from '../../spaces/models/space-env.model'\nimport { dbFileFromSpace } from '../../spaces/utils/paths'\nimport { haveSpaceEnvPermissions } from '../../spaces/utils/permissions'\nimport {\n DEPTH,\n LOCK_DISCOVERY_PROP,\n NS_PREFIX,\n PRECONDITION,\n PROPPATCH_METHOD,\n PROPPATCH_MODIFIED_PROPS,\n PROPPATCH_PROP_UPDATE,\n PROPPATCH_SUPPORTED_PROPS,\n PROPSTAT,\n STANDARD_PROPS,\n XML_CONTENT_TYPE\n} from '../constants/webdav'\nimport { IfHeaderDecorator } from '../decorators/if-header.decorator'\nimport { FastifyDAVRequest, WebDAVLock } from '../interfaces/webdav.interface'\nimport { extractAllTokens, extractOneToken } from '../utils/if-header'\nimport { DAV_ERROR_RES, LOCK_DISCOVERY, LOCK_PROP, MULTI_STATUS, PROP, PROP_STAT } from '../utils/webdav'\nimport { xmlBuild } from '../utils/xml'\nimport { WebDAVSpaces } from './webdav-spaces.service'\n\n@Injectable()\nexport class WebDAVMethods {\n private readonly logger = new Logger(WebDAVMethods.name)\n\n constructor(\n private readonly webDAVHandler: WebDAVSpaces,\n private readonly filesManager: FilesManager,\n private readonly filesLockManager: FilesLockManager\n ) {}\n\n async headOrGet(req: FastifyDAVRequest, res: FastifyReply, repository: string): Promise<StreamableFile> {\n if (repository === SPACE_REPOSITORY.FILES && !req.space.inSharesList) {\n const sendFile = this.filesManager.sendFileFromSpace(req.space)\n try {\n await sendFile.checks()\n return await sendFile.stream(req, res)\n } catch (e) {\n return this.handleError(req, res, e)\n }\n }\n this.logger.warn(`Not allowed on this resource : ${repository}`)\n return res.status(HttpStatus.FORBIDDEN).send('Not allowed on this resource')\n }\n\n @IfHeaderDecorator()\n async lock(req: FastifyDAVRequest, res: FastifyReply) {\n const isLockRefresh = !req.dav.body\n const rExists = await isPathExists(req.space.realPath)\n\n if (isLockRefresh) {\n // if the body has no content, the request must refresh the lock\n if (!rExists) {\n this.logger.warn('Lock refresh must specify an existing resource')\n return res.status(HttpStatus.BAD_REQUEST).send('Lock refresh must specify an existing resource')\n }\n return this.lockRefresh(req, res, req.space.dbFile.path)\n }\n if (!rExists) {\n if (!haveSpaceEnvPermissions(req.space, SPACE_OPERATION.ADD)) {\n this.logger.warn(`is not allowed to create on this space : *${req.space.alias}* (${req.space.id}) : ${req.space.url}`)\n return res.status(HttpStatus.FORBIDDEN).send('You are not allowed to do this action')\n }\n if (!(await isPathExists(dirName(req.space.realPath)))) {\n return res.status(HttpStatus.CONFLICT).send('Parent must exists')\n }\n }\n\n const davLock: WebDAVLock = {\n lockroot: req.dav.url,\n locktoken: null, // created later\n lockscope: req.dav.lock.lockscope,\n owner: req.dav.lock.owner\n }\n\n const [ok, fileLock] = await this.filesLockManager.create(req.user, req.space.dbFile, req.dav.depth, req.dav.lock.timeout, davLock)\n if (ok) {\n // Locking unmapped URLs: must create an empty resource (that is not a collection)\n if (!rExists) {\n // checkLocks set to false because the conflicts are already checked in `filesLockManager.create` method\n await this.filesManager.mkFile(req.user, req.space, false, false, false)\n }\n const lockProp = LOCK_PROP([fileLock])\n return res\n .header('lock-token', `<${davLock.locktoken}>`)\n .type(XML_CONTENT_TYPE)\n .status(rExists ? HttpStatus.OK : HttpStatus.CREATED)\n .send(xmlBuild(lockProp))\n } else {\n return DAV_ERROR_RES(HttpStatus.LOCKED, PRECONDITION.LOCK_CONFLICT, res, fileLock.davLock?.lockroot || fileLock.dbFilePath)\n }\n }\n\n @IfHeaderDecorator()\n async unlock(req: FastifyDAVRequest, res: FastifyReply) {\n if (!(await isPathExists(req.space.realPath))) {\n this.logger.warn(`Unable to unlock ${req.dav.url} : resource does not exist`)\n return res.status(HttpStatus.NOT_FOUND).send(req.dav.url)\n }\n\n const lock = await this.filesLockManager.isLockedWithToken(req.dav.lock.token, req.space.dbFile.path)\n if (!lock) {\n this.logger.warn(`Lock token does not exist or not match URL : ${req.dav.lock.token}`)\n return DAV_ERROR_RES(HttpStatus.CONFLICT, PRECONDITION.LOCK_TOKEN_MISMATCH, res)\n }\n if (req.user.id !== lock.owner.id) {\n return res.status(HttpStatus.FORBIDDEN).send('Token was created by another user')\n }\n\n await this.filesLockManager.removeLock(lock.key)\n return res.status(HttpStatus.NO_CONTENT).send()\n }\n\n @IfHeaderDecorator()\n async propfind(req: FastifyDAVRequest, res: FastifyReply, repository: string): Promise<string> {\n if (repository === SPACE_REPOSITORY.FILES && !req.space.inSharesList) {\n if (!(await isPathExists(req.space.realPath))) {\n return res.status(HttpStatus.NOT_FOUND).send(req.dav.url)\n }\n }\n\n const responses: any[] = []\n let requestedProps: string[]\n let locks: Record<string, FileLock> = {}\n\n if (req.dav.propfindMode === PROPSTAT.PROP) {\n // ignores all unknown properties (non-RFC compliant but avoids generating too much content, faster)\n requestedProps = Object.keys(req.dav.body.propfind.prop).filter((prop: string) => STANDARD_PROPS.indexOf(prop) > -1)\n } else {\n requestedProps = STANDARD_PROPS\n }\n\n // Searches all child locks (only for real files) & ignores /webdav/shares endpoint (special case)\n if (req.dav.propfindMode !== PROPSTAT.PROPNAME && repository === SPACE_REPOSITORY.FILES && !req.space.inSharesList) {\n if (req.dav.depth === DEPTH.RESOURCE) {\n // match depth '0'\n locks = await this.filesLockManager.browseLocks(req.space.dbFile)\n } else {\n // match depth '1' or 'infinity'\n locks = await this.filesLockManager.browseParentChildLocks(req.space.dbFile)\n }\n }\n\n for await (const f of this.webDAVHandler.propfind(req, repository)) {\n let prop: any\n if (req.dav.propfindMode === PROPSTAT.PROPNAME) {\n prop = { ...Object.fromEntries(requestedProps.map((x) => [`${NS_PREFIX}:${x}`, ''])) }\n } else {\n prop = {}\n for (const p of requestedProps) {\n let fP: any\n if (p === LOCK_DISCOVERY_PROP) {\n fP = repository === SPACE_REPOSITORY.FILES && f.name in locks ? LOCK_DISCOVERY([locks[f.name]]) : null\n } else {\n fP = f[p]\n }\n if (fP !== undefined) prop[`${NS_PREFIX}:${p}`] = fP\n }\n }\n responses.push(PROP_STAT(f.href, PROP(prop, req.dav.httpVersion, HttpStatus.OK)))\n }\n const propfind = xmlBuild(MULTI_STATUS(responses))\n return res.type(XML_CONTENT_TYPE).status(HttpStatus.MULTI_STATUS).send(propfind)\n }\n\n @IfHeaderDecorator()\n async put(req: FastifyDAVRequest, res: FastifyReply): Promise<FastifyReply> {\n let rExists: boolean\n try {\n rExists = await this.filesManager.saveStream(req.user, req.space, req, {\n dav: {\n depth: req.dav.depth,\n lockTokens: extractAllTokens(req.dav.ifHeaders)\n }\n })\n } catch (e) {\n return this.handleError(req, res, e)\n }\n return res\n .header('etag', genEtag(null, req.space.realPath))\n .status(rExists ? HttpStatus.NO_CONTENT : HttpStatus.CREATED)\n .send()\n }\n\n @IfHeaderDecorator()\n async delete(req: FastifyDAVRequest, res: FastifyReply) {\n try {\n await this.filesManager.delete(req.user, req.space, { lockTokens: extractAllTokens(req.dav.ifHeaders) })\n } catch (e) {\n return this.handleError(req, res, e)\n }\n return res.status(HttpStatus.NO_CONTENT).send()\n }\n\n @IfHeaderDecorator()\n async proppatch(req: FastifyDAVRequest, res: FastifyReply) {\n /* only support 'time modifications' */\n if (!(await isPathExists(req.space.realPath))) {\n return res.status(HttpStatus.NOT_FOUND).send(req.dav.url)\n }\n\n // check locks\n try {\n await this.filesLockManager.checkConflicts(req.space.dbFile, req.dav.depth, {\n userId: req.user.id,\n lockTokens: extractAllTokens(req.dav.ifHeaders)\n })\n } catch (e) {\n return this.handleError(req, res, e)\n }\n\n // evaluate props and return multistatus if errors\n req.dav.proppatch = { props: {}, errors: [] }\n for (const action of Object.keys(req.dav.body[PROPPATCH_PROP_UPDATE])) {\n if (Object.values(PROPPATCH_METHOD).indexOf(action) === -1) {\n const msg = `Unknown tag : expected ${PROPPATCH_METHOD.SET} or ${PROPPATCH_METHOD.REMOVE}`\n this.logger.debug(msg)\n return res.status(HttpStatus.BAD_REQUEST).send(msg)\n }\n\n if (Array.isArray(req.dav.body[PROPPATCH_PROP_UPDATE][action])) {\n if (Object.keys(req.dav.body[PROPPATCH_PROP_UPDATE][action][0])[0] === PROPSTAT.PROP) {\n req.dav.body[PROPPATCH_PROP_UPDATE][action] = {\n [PROPSTAT.PROP]: req.dav.body[PROPPATCH_PROP_UPDATE][action].map((e: any) => e[PROPSTAT.PROP])\n }\n }\n }\n\n if (Object.keys(req.dav.body[PROPPATCH_PROP_UPDATE][action])[0] !== PROPSTAT.PROP) {\n const msg = `Unknown tag : expected ${PROPSTAT.PROP}`\n this.logger.debug(msg)\n return res.status(HttpStatus.BAD_REQUEST).send(msg)\n }\n\n if (!Array.isArray(req.dav.body[PROPPATCH_PROP_UPDATE][action][PROPSTAT.PROP])) {\n req.dav.body[PROPPATCH_PROP_UPDATE][action][PROPSTAT.PROP] = [req.dav.body[PROPPATCH_PROP_UPDATE][action][PROPSTAT.PROP]]\n }\n\n for (const prop of req.dav.body[PROPPATCH_PROP_UPDATE][action][PROPSTAT.PROP] as Record<string, string>[]) {\n for (let [name, value] of Object.entries(prop)) {\n if (action === PROPPATCH_METHOD.REMOVE) {\n value = null\n this.logger.debug(`Proppatch remove method not handled : ${name} -> ${value}`)\n }\n if (PROPPATCH_SUPPORTED_PROPS.indexOf(name) === -1) {\n req.dav.proppatch.errors.push(\n PROP(\n { [`${NS_PREFIX}:${name}`]: null },\n req.dav.httpVersion,\n HttpStatus.FORBIDDEN,\n STANDARD_PROPS.indexOf(name) > -1 ? PRECONDITION.PROTECTED_PROPERTY : undefined\n )\n )\n continue\n }\n req.dav.proppatch.props[name] = value\n }\n }\n }\n\n if (req.dav.proppatch.errors.length) {\n // convert all passed props to failed dependency\n for (const name of Object.keys(req.dav.proppatch.props)) {\n req.dav.proppatch.errors.push(PROP({ [`${NS_PREFIX}:${name}`]: null }, req.dav.httpVersion, HttpStatus.FAILED_DEPENDENCY))\n }\n const proppatch = xmlBuild(MULTI_STATUS(PROP_STAT(encodeUrl(req.dav.url), req.dav.proppatch.errors)))\n return res.status(HttpStatus.MULTI_STATUS).type(XML_CONTENT_TYPE).send(proppatch)\n }\n\n // apply modifications\n let atLeastOneError = false\n const states: Record<string, boolean> = {}\n for (const [name, value] of Object.entries(req.dav.proppatch.props)) {\n if (PROPPATCH_MODIFIED_PROPS.indexOf(name) > -1) {\n try {\n await this.filesManager.touch(req.user, req.space, currentTimeStamp(new Date(value)), false)\n } catch (e) {\n this.logger.error(`${this.proppatch.name} - unable to modify mtime on ${req.dav.url} : ${e}`)\n states[name] = false\n atLeastOneError = true\n }\n }\n // hook: we let the known Win32* properties pass to return a consistent result\n states[name] = true\n }\n\n const props = []\n for (const [name, state] of Object.entries(states)) {\n props.push(\n PROP(\n { [`${NS_PREFIX}:${name}`]: null },\n req.dav.httpVersion,\n state ? (atLeastOneError ? HttpStatus.FAILED_DEPENDENCY : HttpStatus.OK) : HttpStatus.BAD_REQUEST\n )\n )\n }\n const proppatch = xmlBuild(MULTI_STATUS(PROP_STAT(encodeUrl(req.dav.url), props)))\n return res.type(XML_CONTENT_TYPE).status(HttpStatus.MULTI_STATUS).send(proppatch)\n }\n\n @IfHeaderDecorator()\n async mkcol(req: FastifyDAVRequest, res: FastifyReply) {\n try {\n await this.filesManager.mkDir(req.user, req.space, false, { depth: req.dav.depth, lockTokens: extractAllTokens(req.dav.ifHeaders) })\n } catch (e) {\n return this.handleError(req, res, e)\n }\n return res.status(HttpStatus.CREATED).send()\n }\n\n @IfHeaderDecorator()\n async copyMove(req: FastifyDAVRequest, res: FastifyReply) {\n const dstSpace: SpaceEnv = await this.webDAVHandler.spaceEnv(req.user, req.dav.copyMove.destination)\n if (!dstSpace) {\n this.logger.warn(`Space not found for destination : ${req.dav.copyMove.destination}`)\n return res.status(HttpStatus.NOT_FOUND).send(req.dav.copyMove.destination)\n }\n const dstExisted = await isPathExists(dstSpace.realPath)\n // We must evaluate the if-headers on the destination\n const fakeDstReq = {\n dav: { ...req.dav, url: req.dav.copyMove.destination },\n user: req.user,\n space: dstSpace\n } as FastifyDAVRequest\n if (!(await this.evaluateIfHeaders(fakeDstReq, res))) {\n // if there is an error the response is generated inside the `evaluateIfHeaders` function\n return\n }\n try {\n await this.filesManager.copyMove(req.user, req.space, dstSpace, req.dav.copyMove.isMove, req.dav.copyMove.overwrite, false, {\n depth: req.dav.depth,\n lockTokens: extractAllTokens(req.dav.ifHeaders)\n })\n } catch (e) {\n return this.handleError(req, res, e, dstSpace.url)\n }\n return res.status(dstExisted ? HttpStatus.NO_CONTENT : HttpStatus.CREATED).send()\n }\n\n protected async evaluateIfHeaders(req: FastifyDAVRequest, res: FastifyReply): Promise<boolean> {\n if (!req.dav.ifHeaders) return true\n const errors: string[] = []\n let lastPath = null\n let lastSpaceEnv: SpaceEnv\n let lastRPath = undefined\n let lastEtag = undefined // for now, we only generate one etag type (weak)\n let atLeastOneOk = false\n\n for (const condition of req.dav.ifHeaders) {\n if (condition.path) {\n if (condition.path !== lastPath) {\n lastPath = condition.path\n lastSpaceEnv = await this.webDAVHandler.spaceEnv(req.user, lastPath)\n }\n // the path will be the same across conditions\n if (!lastSpaceEnv) {\n this.logger.warn(`If Header : path mismatch (${condition.path})`)\n return false\n }\n } else {\n lastPath = req.dav.url\n lastSpaceEnv = req.space\n }\n\n if (condition.haveLock) {\n try {\n const dbFile = dbFileFromSpace(req.user.id, lastSpaceEnv)\n const match = !!(await this.filesLockManager.getLocksByPath(dbFile)).length\n if (condition.haveLock.mustMatch !== match) {\n errors.push(`have lock condition mismatch (${condition.haveLock.mustMatch} != ${match})`)\n continue\n }\n } catch (e) {\n errors.push(`have lock condition mismatch : ${e.message}`)\n continue\n }\n }\n\n if (condition.token) {\n const token = await this.filesLockManager.getLockByToken(condition.token.value)\n const match = token && lastPath.startsWith(token.davLock?.lockroot)\n if (condition.token.mustMatch !== match) {\n if (!token) {\n errors.push(`lock token not found`)\n } else {\n errors.push(`lock token url mismatch (${lastPath} is not a child of ${token.davLock?.lockroot})`)\n }\n continue\n }\n }\n\n if (condition.etag) {\n if (lastEtag === undefined) {\n if (lastRPath === undefined) {\n lastRPath = (await isPathExists(req.space.realPath)) ? req.space.realPath : null\n }\n lastEtag = lastRPath ? genEtag(null, lastRPath) : null\n }\n const match = lastEtag === condition.etag.value\n if (condition.etag.mustMatch !== match) {\n errors.push(`etag mismatch (${condition.etag.value} != ${lastEtag})`)\n continue\n }\n }\n\n atLeastOneOk = true\n break\n }\n\n if (!atLeastOneOk) {\n this.logger.warn(`If header condition failed : ${errors.join(', ')}`)\n res.status(HttpStatus.PRECONDITION_FAILED).send('If header condition failed')\n }\n return atLeastOneOk\n }\n\n private async lockRefresh(req: FastifyDAVRequest, res: FastifyReply, dbFilePath: string) {\n if (req.dav?.ifHeaders?.length !== 1) {\n this.logger.warn('Expected a lock token (only one lock may be refreshed at a time)')\n return res.status(HttpStatus.BAD_REQUEST).send('Expected a lock token (only one lock may be refreshed at a time)')\n }\n\n let token: string\n try {\n token = extractOneToken(req.dav.ifHeaders)\n } catch (e) {\n this.logger.warn(`${this.lockRefresh.name} - unable to extract token : ${JSON.stringify(req.dav.ifHeaders)} (${e})`)\n return res.status(HttpStatus.BAD_REQUEST).send('Unable to extract token')\n }\n\n const lock = await this.filesLockManager.isLockedWithToken(token, dbFilePath)\n if (!lock) {\n this.logger.warn(`Lock token does not exist or not match URL : ${token}`)\n return DAV_ERROR_RES(HttpStatus.PRECONDITION_FAILED, PRECONDITION.LOCK_TOKEN_MISMATCH, res)\n }\n if (lock.owner.id !== req.user.id) {\n this.logger.warn(`Lock token does not match owner : ${lock.owner.login} != ${req.user.login}`)\n return res.status(HttpStatus.FORBIDDEN).send('Lock token does not match owner')\n }\n\n await this.filesLockManager.refreshLockTimeout(lock, req.dav.lock.timeout)\n const lockProp = LOCK_PROP([lock])\n return res.type(XML_CONTENT_TYPE).status(HttpStatus.OK).send(xmlBuild(lockProp))\n }\n\n private handleError(req: FastifyDAVRequest, res: FastifyReply, e: any, toUrl?: string) {\n this.logger.error(`Unable to ${req.method} ${req.dav.url}${toUrl ? ` -> ${toUrl}` : ''} : ${e.message}`)\n if (e instanceof LockConflict) {\n return DAV_ERROR_RES(HttpStatus.LOCKED, PRECONDITION.LOCK_CONFLICT, res, e.lock.davLock?.lockroot || e.lock.dbFilePath)\n } else if (e instanceof FileError) {\n return res.status(e.httpCode).send(e.message)\n }\n throw new HttpException(e.message, HttpStatus.INTERNAL_SERVER_ERROR)\n }\n}\n"],"names":["WebDAVMethods","headOrGet","req","res","repository","SPACE_REPOSITORY","FILES","space","inSharesList","sendFile","filesManager","sendFileFromSpace","checks","stream","e","handleError","logger","warn","status","HttpStatus","FORBIDDEN","send","lock","isLockRefresh","dav","body","rExists","isPathExists","realPath","BAD_REQUEST","lockRefresh","dbFile","path","haveSpaceEnvPermissions","SPACE_OPERATION","ADD","alias","id","url","dirName","CONFLICT","davLock","lockroot","locktoken","lockscope","owner","ok","fileLock","filesLockManager","create","user","depth","timeout","mkFile","lockProp","LOCK_PROP","header","type","XML_CONTENT_TYPE","OK","CREATED","xmlBuild","DAV_ERROR_RES","LOCKED","PRECONDITION","LOCK_CONFLICT","dbFilePath","unlock","NOT_FOUND","isLockedWithToken","token","LOCK_TOKEN_MISMATCH","removeLock","key","NO_CONTENT","propfind","responses","requestedProps","locks","propfindMode","PROPSTAT","PROP","Object","keys","prop","filter","STANDARD_PROPS","indexOf","PROPNAME","DEPTH","RESOURCE","browseLocks","browseParentChildLocks","f","webDAVHandler","fromEntries","map","x","NS_PREFIX","p","fP","LOCK_DISCOVERY_PROP","name","LOCK_DISCOVERY","undefined","push","PROP_STAT","href","httpVersion","MULTI_STATUS","put","saveStream","lockTokens","extractAllTokens","ifHeaders","genEtag","delete","proppatch","checkConflicts","userId","props","errors","action","PROPPATCH_PROP_UPDATE","values","PROPPATCH_METHOD","msg","SET","REMOVE","debug","Array","isArray","value","entries","PROPPATCH_SUPPORTED_PROPS","PROTECTED_PROPERTY","length","FAILED_DEPENDENCY","encodeUrl","atLeastOneError","states","PROPPATCH_MODIFIED_PROPS","touch","currentTimeStamp","Date","error","state","mkcol","mkDir","copyMove","dstSpace","spaceEnv","destination","dstExisted","fakeDstReq","evaluateIfHeaders","isMove","overwrite","lastPath","lastSpaceEnv","lastRPath","lastEtag","atLeastOneOk","condition","haveLock","dbFileFromSpace","match","getLocksByPath","mustMatch","message","getLockByToken","startsWith","etag","join","PRECONDITION_FAILED","extractOneToken","JSON","stringify","login","refreshLockTimeout","toUrl","method","LockConflict","FileError","httpCode","HttpException","INTERNAL_SERVER_ERROR","Logger"],"mappings":"AAAA;;;;CAIC;;;;+BAoCYA;;;eAAAA;;;wBAlCiE;yBACjD;wBACe;2BAElB;+BACG;yCACI;qCACJ;uBACkB;wBACG;uBAElB;6BACQ;wBAajC;mCAC2B;iCACY;0BACI;yBACsC;qBAC/D;qCACI;;;;;;;;;;AAGtB,IAAA,AAAMA,gBAAN,MAAMA;IASX,MAAMC,UAAUC,GAAsB,EAAEC,GAAiB,EAAEC,UAAkB,EAA2B;QACtG,IAAIA,eAAeC,wBAAgB,CAACC,KAAK,IAAI,CAACJ,IAAIK,KAAK,CAACC,YAAY,EAAE;YACpE,MAAMC,WAAW,IAAI,CAACC,YAAY,CAACC,iBAAiB,CAACT,IAAIK,KAAK;YAC9D,IAAI;gBACF,MAAME,SAASG,MAAM;gBACrB,OAAO,MAAMH,SAASI,MAAM,CAACX,KAAKC;YACpC,EAAE,OAAOW,GAAG;gBACV,OAAO,IAAI,CAACC,WAAW,CAACb,KAAKC,KAAKW;YACpC;QACF;QACA,IAAI,CAACE,MAAM,CAACC,IAAI,CAAC,CAAC,+BAA+B,EAAEb,YAAY;QAC/D,OAAOD,IAAIe,MAAM,CAACC,kBAAU,CAACC,SAAS,EAAEC,IAAI,CAAC;IAC/C;IAEA,MACMC,KAAKpB,GAAsB,EAAEC,GAAiB,EAAE;QACpD,MAAMoB,gBAAgB,CAACrB,IAAIsB,GAAG,CAACC,IAAI;QACnC,MAAMC,UAAU,MAAMC,IAAAA,mBAAY,EAACzB,IAAIK,KAAK,CAACqB,QAAQ;QAErD,IAAIL,eAAe;YACjB,gEAAgE;YAChE,IAAI,CAACG,SAAS;gBACZ,IAAI,CAACV,MAAM,CAACC,IAAI,CAAC;gBACjB,OAAOd,IAAIe,MAAM,CAACC,kBAAU,CAACU,WAAW,EAAER,IAAI,CAAC;YACjD;YACA,OAAO,IAAI,CAACS,WAAW,CAAC5B,KAAKC,KAAKD,IAAIK,KAAK,CAACwB,MAAM,CAACC,IAAI;QACzD;QACA,IAAI,CAACN,SAAS;YACZ,IAAI,CAACO,IAAAA,oCAAuB,EAAC/B,IAAIK,KAAK,EAAE2B,uBAAe,CAACC,GAAG,GAAG;gBAC5D,IAAI,CAACnB,MAAM,CAACC,IAAI,CAAC,CAAC,0CAA0C,EAAEf,IAAIK,KAAK,CAAC6B,KAAK,CAAC,GAAG,EAAElC,IAAIK,KAAK,CAAC8B,EAAE,CAAC,IAAI,EAAEnC,IAAIK,KAAK,CAAC+B,GAAG,EAAE;gBACrH,OAAOnC,IAAIe,MAAM,CAACC,kBAAU,CAACC,SAAS,EAAEC,IAAI,CAAC;YAC/C;YACA,IAAI,CAAE,MAAMM,IAAAA,mBAAY,EAACY,IAAAA,cAAO,EAACrC,IAAIK,KAAK,CAACqB,QAAQ,IAAK;gBACtD,OAAOzB,IAAIe,MAAM,CAACC,kBAAU,CAACqB,QAAQ,EAAEnB,IAAI,CAAC;YAC9C;QACF;QAEA,MAAMoB,UAAsB;YAC1BC,UAAUxC,IAAIsB,GAAG,CAACc,GAAG;YACrBK,WAAW;YACXC,WAAW1C,IAAIsB,GAAG,CAACF,IAAI,CAACsB,SAAS;YACjCC,OAAO3C,IAAIsB,GAAG,CAACF,IAAI,CAACuB,KAAK;QAC3B;QAEA,MAAM,CAACC,IAAIC,SAAS,GAAG,MAAM,IAAI,CAACC,gBAAgB,CAACC,MAAM,CAAC/C,IAAIgD,IAAI,EAAEhD,IAAIK,KAAK,CAACwB,MAAM,EAAE7B,IAAIsB,GAAG,CAAC2B,KAAK,EAAEjD,IAAIsB,GAAG,CAACF,IAAI,CAAC8B,OAAO,EAAEX;QAC3H,IAAIK,IAAI;YACN,kFAAkF;YAClF,IAAI,CAACpB,SAAS;gBACZ,wGAAwG;gBACxG,MAAM,IAAI,CAAChB,YAAY,CAAC2C,MAAM,CAACnD,IAAIgD,IAAI,EAAEhD,IAAIK,KAAK,EAAE,OAAO,OAAO;YACpE;YACA,MAAM+C,WAAWC,IAAAA,kBAAS,EAAC;gBAACR;aAAS;YACrC,OAAO5C,IACJqD,MAAM,CAAC,cAAc,CAAC,CAAC,EAAEf,QAAQE,SAAS,CAAC,CAAC,CAAC,EAC7Cc,IAAI,CAACC,wBAAgB,EACrBxC,MAAM,CAACQ,UAAUP,kBAAU,CAACwC,EAAE,GAAGxC,kBAAU,CAACyC,OAAO,EACnDvC,IAAI,CAACwC,IAAAA,aAAQ,EAACP;QACnB,OAAO;YACL,OAAOQ,IAAAA,sBAAa,EAAC3C,kBAAU,CAAC4C,MAAM,EAAEC,oBAAY,CAACC,aAAa,EAAE9D,KAAK4C,SAASN,OAAO,EAAEC,YAAYK,SAASmB,UAAU;QAC5H;IACF;IAEA,MACMC,OAAOjE,GAAsB,EAAEC,GAAiB,EAAE;QACtD,IAAI,CAAE,MAAMwB,IAAAA,mBAAY,EAACzB,IAAIK,KAAK,CAACqB,QAAQ,GAAI;YAC7C,IAAI,CAACZ,MAAM,CAACC,IAAI,CAAC,CAAC,iBAAiB,EAAEf,IAAIsB,GAAG,CAACc,GAAG,CAAC,0BAA0B,CAAC;YAC5E,OAAOnC,IAAIe,MAAM,CAACC,kBAAU,CAACiD,SAAS,EAAE/C,IAAI,CAACnB,IAAIsB,GAAG,CAACc,GAAG;QAC1D;QAEA,MAAMhB,OAAO,MAAM,IAAI,CAAC0B,gBAAgB,CAACqB,iBAAiB,CAACnE,IAAIsB,GAAG,CAACF,IAAI,CAACgD,KAAK,EAAEpE,IAAIK,KAAK,CAACwB,MAAM,CAACC,IAAI;QACpG,IAAI,CAACV,MAAM;YACT,IAAI,CAACN,MAAM,CAACC,IAAI,CAAC,CAAC,6CAA6C,EAAEf,IAAIsB,GAAG,CAACF,IAAI,CAACgD,KAAK,EAAE;YACrF,OAAOR,IAAAA,sBAAa,EAAC3C,kBAAU,CAACqB,QAAQ,EAAEwB,oBAAY,CAACO,mBAAmB,EAAEpE;QAC9E;QACA,IAAID,IAAIgD,IAAI,CAACb,EAAE,KAAKf,KAAKuB,KAAK,CAACR,EAAE,EAAE;YACjC,OAAOlC,IAAIe,MAAM,CAACC,kBAAU,CAACC,SAAS,EAAEC,IAAI,CAAC;QAC/C;QAEA,MAAM,IAAI,CAAC2B,gBAAgB,CAACwB,UAAU,CAAClD,KAAKmD,GAAG;QAC/C,OAAOtE,IAAIe,MAAM,CAACC,kBAAU,CAACuD,UAAU,EAAErD,IAAI;IAC/C;IAEA,MACMsD,SAASzE,GAAsB,EAAEC,GAAiB,EAAEC,UAAkB,EAAmB;QAC7F,IAAIA,eAAeC,wBAAgB,CAACC,KAAK,IAAI,CAACJ,IAAIK,KAAK,CAACC,YAAY,EAAE;YACpE,IAAI,CAAE,MAAMmB,IAAAA,mBAAY,EAACzB,IAAIK,KAAK,CAACqB,QAAQ,GAAI;gBAC7C,OAAOzB,IAAIe,MAAM,CAACC,kBAAU,CAACiD,SAAS,EAAE/C,IAAI,CAACnB,IAAIsB,GAAG,CAACc,GAAG;YAC1D;QACF;QAEA,MAAMsC,YAAmB,EAAE;QAC3B,IAAIC;QACJ,IAAIC,QAAkC,CAAC;QAEvC,IAAI5E,IAAIsB,GAAG,CAACuD,YAAY,KAAKC,gBAAQ,CAACC,IAAI,EAAE;YAC1C,oGAAoG;YACpGJ,iBAAiBK,OAAOC,IAAI,CAACjF,IAAIsB,GAAG,CAACC,IAAI,CAACkD,QAAQ,CAACS,IAAI,EAAEC,MAAM,CAAC,CAACD,OAAiBE,sBAAc,CAACC,OAAO,CAACH,QAAQ,CAAC;QACpH,OAAO;YACLP,iBAAiBS,sBAAc;QACjC;QAEA,kGAAkG;QAClG,IAAIpF,IAAIsB,GAAG,CAACuD,YAAY,KAAKC,gBAAQ,CAACQ,QAAQ,IAAIpF,eAAeC,wBAAgB,CAACC,KAAK,IAAI,CAACJ,IAAIK,KAAK,CAACC,YAAY,EAAE;YAClH,IAAIN,IAAIsB,GAAG,CAAC2B,KAAK,KAAKsC,aAAK,CAACC,QAAQ,EAAE;gBACpC,kBAAkB;gBAClBZ,QAAQ,MAAM,IAAI,CAAC9B,gBAAgB,CAAC2C,WAAW,CAACzF,IAAIK,KAAK,CAACwB,MAAM;YAClE,OAAO;gBACL,gCAAgC;gBAChC+C,QAAQ,MAAM,IAAI,CAAC9B,gBAAgB,CAAC4C,sBAAsB,CAAC1F,IAAIK,KAAK,CAACwB,MAAM;YAC7E;QACF;QAEA,WAAW,MAAM8D,KAAK,IAAI,CAACC,aAAa,CAACnB,QAAQ,CAACzE,KAAKE,YAAa;YAClE,IAAIgF;YACJ,IAAIlF,IAAIsB,GAAG,CAACuD,YAAY,KAAKC,gBAAQ,CAACQ,QAAQ,EAAE;gBAC9CJ,OAAO;oBAAE,GAAGF,OAAOa,WAAW,CAAClB,eAAemB,GAAG,CAAC,CAACC,IAAM;4BAAC,GAAGC,iBAAS,CAAC,CAAC,EAAED,GAAG;4BAAE;yBAAG,EAAE;gBAAC;YACvF,OAAO;gBACLb,OAAO,CAAC;gBACR,KAAK,MAAMe,KAAKtB,eAAgB;oBAC9B,IAAIuB;oBACJ,IAAID,MAAME,2BAAmB,EAAE;wBAC7BD,KAAKhG,eAAeC,wBAAgB,CAACC,KAAK,IAAIuF,EAAES,IAAI,IAAIxB,QAAQyB,IAAAA,uBAAc,EAAC;4BAACzB,KAAK,CAACe,EAAES,IAAI,CAAC;yBAAC,IAAI;oBACpG,OAAO;wBACLF,KAAKP,CAAC,CAACM,EAAE;oBACX;oBACA,IAAIC,OAAOI,WAAWpB,IAAI,CAAC,GAAGc,iBAAS,CAAC,CAAC,EAAEC,GAAG,CAAC,GAAGC;gBACpD;YACF;YACAxB,UAAU6B,IAAI,CAACC,IAAAA,kBAAS,EAACb,EAAEc,IAAI,EAAE1B,IAAAA,aAAI,EAACG,MAAMlF,IAAIsB,GAAG,CAACoF,WAAW,EAAEzF,kBAAU,CAACwC,EAAE;QAChF;QACA,MAAMgB,WAAWd,IAAAA,aAAQ,EAACgD,IAAAA,qBAAY,EAACjC;QACvC,OAAOzE,IAAIsD,IAAI,CAACC,wBAAgB,EAAExC,MAAM,CAACC,kBAAU,CAAC0F,YAAY,EAAExF,IAAI,CAACsD;IACzE;IAEA,MACMmC,IAAI5G,GAAsB,EAAEC,GAAiB,EAAyB;QAC1E,IAAIuB;QACJ,IAAI;YACFA,UAAU,MAAM,IAAI,CAAChB,YAAY,CAACqG,UAAU,CAAC7G,IAAIgD,IAAI,EAAEhD,IAAIK,KAAK,EAAEL,KAAK;gBACrEsB,KAAK;oBACH2B,OAAOjD,IAAIsB,GAAG,CAAC2B,KAAK;oBACpB6D,YAAYC,IAAAA,0BAAgB,EAAC/G,IAAIsB,GAAG,CAAC0F,SAAS;gBAChD;YACF;QACF,EAAE,OAAOpG,GAAG;YACV,OAAO,IAAI,CAACC,WAAW,CAACb,KAAKC,KAAKW;QACpC;QACA,OAAOX,IACJqD,MAAM,CAAC,QAAQ2D,IAAAA,cAAO,EAAC,MAAMjH,IAAIK,KAAK,CAACqB,QAAQ,GAC/CV,MAAM,CAACQ,UAAUP,kBAAU,CAACuD,UAAU,GAAGvD,kBAAU,CAACyC,OAAO,EAC3DvC,IAAI;IACT;IAEA,MACM+F,OAAOlH,GAAsB,EAAEC,GAAiB,EAAE;QACtD,IAAI;YACF,MAAM,IAAI,CAACO,YAAY,CAAC0G,MAAM,CAAClH,IAAIgD,IAAI,EAAEhD,IAAIK,KAAK,EAAE;gBAAEyG,YAAYC,IAAAA,0BAAgB,EAAC/G,IAAIsB,GAAG,CAAC0F,SAAS;YAAE;QACxG,EAAE,OAAOpG,GAAG;YACV,OAAO,IAAI,CAACC,WAAW,CAACb,KAAKC,KAAKW;QACpC;QACA,OAAOX,IAAIe,MAAM,CAACC,kBAAU,CAACuD,UAAU,EAAErD,IAAI;IAC/C;IAEA,MACMgG,UAAUnH,GAAsB,EAAEC,GAAiB,EAAE;QACzD,qCAAqC,GACrC,IAAI,CAAE,MAAMwB,IAAAA,mBAAY,EAACzB,IAAIK,KAAK,CAACqB,QAAQ,GAAI;YAC7C,OAAOzB,IAAIe,MAAM,CAACC,kBAAU,CAACiD,SAAS,EAAE/C,IAAI,CAACnB,IAAIsB,GAAG,CAACc,GAAG;QAC1D;QAEA,cAAc;QACd,IAAI;YACF,MAAM,IAAI,CAACU,gBAAgB,CAACsE,cAAc,CAACpH,IAAIK,KAAK,CAACwB,MAAM,EAAE7B,IAAIsB,GAAG,CAAC2B,KAAK,EAAE;gBAC1EoE,QAAQrH,IAAIgD,IAAI,CAACb,EAAE;gBACnB2E,YAAYC,IAAAA,0BAAgB,EAAC/G,IAAIsB,GAAG,CAAC0F,SAAS;YAChD;QACF,EAAE,OAAOpG,GAAG;YACV,OAAO,IAAI,CAACC,WAAW,CAACb,KAAKC,KAAKW;QACpC;QAEA,kDAAkD;QAClDZ,IAAIsB,GAAG,CAAC6F,SAAS,GAAG;YAAEG,OAAO,CAAC;YAAGC,QAAQ,EAAE;QAAC;QAC5C,KAAK,MAAMC,UAAUxC,OAAOC,IAAI,CAACjF,IAAIsB,GAAG,CAACC,IAAI,CAACkG,6BAAqB,CAAC,EAAG;YACrE,IAAIzC,OAAO0C,MAAM,CAACC,wBAAgB,EAAEtC,OAAO,CAACmC,YAAY,CAAC,GAAG;gBAC1D,MAAMI,MAAM,CAAC,uBAAuB,EAAED,wBAAgB,CAACE,GAAG,CAAC,IAAI,EAAEF,wBAAgB,CAACG,MAAM,EAAE;gBAC1F,IAAI,CAAChH,MAAM,CAACiH,KAAK,CAACH;gBAClB,OAAO3H,IAAIe,MAAM,CAACC,kBAAU,CAACU,WAAW,EAAER,IAAI,CAACyG;YACjD;YAEA,IAAII,MAAMC,OAAO,CAACjI,IAAIsB,GAAG,CAACC,IAAI,CAACkG,6BAAqB,CAAC,CAACD,OAAO,GAAG;gBAC9D,IAAIxC,OAAOC,IAAI,CAACjF,IAAIsB,GAAG,CAACC,IAAI,CAACkG,6BAAqB,CAAC,CAACD,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK1C,gBAAQ,CAACC,IAAI,EAAE;oBACpF/E,IAAIsB,GAAG,CAACC,IAAI,CAACkG,6BAAqB,CAAC,CAACD,OAAO,GAAG;wBAC5C,CAAC1C,gBAAQ,CAACC,IAAI,CAAC,EAAE/E,IAAIsB,GAAG,CAACC,IAAI,CAACkG,6BAAqB,CAAC,CAACD,OAAO,CAAC1B,GAAG,CAAC,CAAClF,IAAWA,CAAC,CAACkE,gBAAQ,CAACC,IAAI,CAAC;oBAC/F;gBACF;YACF;YAEA,IAAIC,OAAOC,IAAI,CAACjF,IAAIsB,GAAG,CAACC,IAAI,CAACkG,6BAAqB,CAAC,CAACD,OAAO,CAAC,CAAC,EAAE,KAAK1C,gBAAQ,CAACC,IAAI,EAAE;gBACjF,MAAM6C,MAAM,CAAC,uBAAuB,EAAE9C,gBAAQ,CAACC,IAAI,EAAE;gBACrD,IAAI,CAACjE,MAAM,CAACiH,KAAK,CAACH;gBAClB,OAAO3H,IAAIe,MAAM,CAACC,kBAAU,CAACU,WAAW,EAAER,IAAI,CAACyG;YACjD;YAEA,IAAI,CAACI,MAAMC,OAAO,CAACjI,IAAIsB,GAAG,CAACC,IAAI,CAACkG,6BAAqB,CAAC,CAACD,OAAO,CAAC1C,gBAAQ,CAACC,IAAI,CAAC,GAAG;gBAC9E/E,IAAIsB,GAAG,CAACC,IAAI,CAACkG,6BAAqB,CAAC,CAACD,OAAO,CAAC1C,gBAAQ,CAACC,IAAI,CAAC,GAAG;oBAAC/E,IAAIsB,GAAG,CAACC,IAAI,CAACkG,6BAAqB,CAAC,CAACD,OAAO,CAAC1C,gBAAQ,CAACC,IAAI,CAAC;iBAAC;YAC3H;YAEA,KAAK,MAAMG,QAAQlF,IAAIsB,GAAG,CAACC,IAAI,CAACkG,6BAAqB,CAAC,CAACD,OAAO,CAAC1C,gBAAQ,CAACC,IAAI,CAAC,CAA8B;gBACzG,KAAK,IAAI,CAACqB,MAAM8B,MAAM,IAAIlD,OAAOmD,OAAO,CAACjD,MAAO;oBAC9C,IAAIsC,WAAWG,wBAAgB,CAACG,MAAM,EAAE;wBACtCI,QAAQ;wBACR,IAAI,CAACpH,MAAM,CAACiH,KAAK,CAAC,CAAC,sCAAsC,EAAE3B,KAAK,IAAI,EAAE8B,OAAO;oBAC/E;oBACA,IAAIE,iCAAyB,CAAC/C,OAAO,CAACe,UAAU,CAAC,GAAG;wBAClDpG,IAAIsB,GAAG,CAAC6F,SAAS,CAACI,MAAM,CAAChB,IAAI,CAC3BxB,IAAAA,aAAI,EACF;4BAAE,CAAC,GAAGiB,iBAAS,CAAC,CAAC,EAAEI,MAAM,CAAC,EAAE;wBAAK,GACjCpG,IAAIsB,GAAG,CAACoF,WAAW,EACnBzF,kBAAU,CAACC,SAAS,EACpBkE,sBAAc,CAACC,OAAO,CAACe,QAAQ,CAAC,IAAItC,oBAAY,CAACuE,kBAAkB,GAAG/B;wBAG1E;oBACF;oBACAtG,IAAIsB,GAAG,CAAC6F,SAAS,CAACG,KAAK,CAAClB,KAAK,GAAG8B;gBAClC;YACF;QACF;QAEA,IAAIlI,IAAIsB,GAAG,CAAC6F,SAAS,CAACI,MAAM,CAACe,MAAM,EAAE;YACnC,gDAAgD;YAChD,KAAK,MAAMlC,QAAQpB,OAAOC,IAAI,CAACjF,IAAIsB,GAAG,CAAC6F,SAAS,CAACG,KAAK,EAAG;gBACvDtH,IAAIsB,GAAG,CAAC6F,SAAS,CAACI,MAAM,CAAChB,IAAI,CAACxB,IAAAA,aAAI,EAAC;oBAAE,CAAC,GAAGiB,iBAAS,CAAC,CAAC,EAAEI,MAAM,CAAC,EAAE;gBAAK,GAAGpG,IAAIsB,GAAG,CAACoF,WAAW,EAAEzF,kBAAU,CAACsH,iBAAiB;YAC1H;YACA,MAAMpB,YAAYxD,IAAAA,aAAQ,EAACgD,IAAAA,qBAAY,EAACH,IAAAA,kBAAS,EAACgC,IAAAA,iBAAS,EAACxI,IAAIsB,GAAG,CAACc,GAAG,GAAGpC,IAAIsB,GAAG,CAAC6F,SAAS,CAACI,MAAM;YAClG,OAAOtH,IAAIe,MAAM,CAACC,kBAAU,CAAC0F,YAAY,EAAEpD,IAAI,CAACC,wBAAgB,EAAErC,IAAI,CAACgG;QACzE;QAEA,sBAAsB;QACtB,IAAIsB,kBAAkB;QACtB,MAAMC,SAAkC,CAAC;QACzC,KAAK,MAAM,CAACtC,MAAM8B,MAAM,IAAIlD,OAAOmD,OAAO,CAACnI,IAAIsB,GAAG,CAAC6F,SAAS,CAACG,KAAK,EAAG;YACnE,IAAIqB,gCAAwB,CAACtD,OAAO,CAACe,QAAQ,CAAC,GAAG;gBAC/C,IAAI;oBACF,MAAM,IAAI,CAAC5F,YAAY,CAACoI,KAAK,CAAC5I,IAAIgD,IAAI,EAAEhD,IAAIK,KAAK,EAAEwI,IAAAA,wBAAgB,EAAC,IAAIC,KAAKZ,SAAS;gBACxF,EAAE,OAAOtH,GAAG;oBACV,IAAI,CAACE,MAAM,CAACiI,KAAK,CAAC,GAAG,IAAI,CAAC5B,SAAS,CAACf,IAAI,CAAC,6BAA6B,EAAEpG,IAAIsB,GAAG,CAACc,GAAG,CAAC,GAAG,EAAExB,GAAG;oBAC5F8H,MAAM,CAACtC,KAAK,GAAG;oBACfqC,kBAAkB;gBACpB;YACF;YACA,8EAA8E;YAC9EC,MAAM,CAACtC,KAAK,GAAG;QACjB;QAEA,MAAMkB,QAAQ,EAAE;QAChB,KAAK,MAAM,CAAClB,MAAM4C,MAAM,IAAIhE,OAAOmD,OAAO,CAACO,QAAS;YAClDpB,MAAMf,IAAI,CACRxB,IAAAA,aAAI,EACF;gBAAE,CAAC,GAAGiB,iBAAS,CAAC,CAAC,EAAEI,MAAM,CAAC,EAAE;YAAK,GACjCpG,IAAIsB,GAAG,CAACoF,WAAW,EACnBsC,QAASP,kBAAkBxH,kBAAU,CAACsH,iBAAiB,GAAGtH,kBAAU,CAACwC,EAAE,GAAIxC,kBAAU,CAACU,WAAW;QAGvG;QACA,MAAMwF,YAAYxD,IAAAA,aAAQ,EAACgD,IAAAA,qBAAY,EAACH,IAAAA,kBAAS,EAACgC,IAAAA,iBAAS,EAACxI,IAAIsB,GAAG,CAACc,GAAG,GAAGkF;QAC1E,OAAOrH,IAAIsD,IAAI,CAACC,wBAAgB,EAAExC,MAAM,CAACC,kBAAU,CAAC0F,YAAY,EAAExF,IAAI,CAACgG;IACzE;IAEA,MACM8B,MAAMjJ,GAAsB,EAAEC,GAAiB,EAAE;QACrD,IAAI;YACF,MAAM,IAAI,CAACO,YAAY,CAAC0I,KAAK,CAAClJ,IAAIgD,IAAI,EAAEhD,IAAIK,KAAK,EAAE,OAAO;gBAAE4C,OAAOjD,IAAIsB,GAAG,CAAC2B,KAAK;gBAAE6D,YAAYC,IAAAA,0BAAgB,EAAC/G,IAAIsB,GAAG,CAAC0F,SAAS;YAAE;QACpI,EAAE,OAAOpG,GAAG;YACV,OAAO,IAAI,CAACC,WAAW,CAACb,KAAKC,KAAKW;QACpC;QACA,OAAOX,IAAIe,MAAM,CAACC,kBAAU,CAACyC,OAAO,EAAEvC,IAAI;IAC5C;IAEA,MACMgI,SAASnJ,GAAsB,EAAEC,GAAiB,EAAE;QACxD,MAAMmJ,WAAqB,MAAM,IAAI,CAACxD,aAAa,CAACyD,QAAQ,CAACrJ,IAAIgD,IAAI,EAAEhD,IAAIsB,GAAG,CAAC6H,QAAQ,CAACG,WAAW;QACnG,IAAI,CAACF,UAAU;YACb,IAAI,CAACtI,MAAM,CAACC,IAAI,CAAC,CAAC,kCAAkC,EAAEf,IAAIsB,GAAG,CAAC6H,QAAQ,CAACG,WAAW,EAAE;YACpF,OAAOrJ,IAAIe,MAAM,CAACC,kBAAU,CAACiD,SAAS,EAAE/C,IAAI,CAACnB,IAAIsB,GAAG,CAAC6H,QAAQ,CAACG,WAAW;QAC3E;QACA,MAAMC,aAAa,MAAM9H,IAAAA,mBAAY,EAAC2H,SAAS1H,QAAQ;QACvD,qDAAqD;QACrD,MAAM8H,aAAa;YACjBlI,KAAK;gBAAE,GAAGtB,IAAIsB,GAAG;gBAAEc,KAAKpC,IAAIsB,GAAG,CAAC6H,QAAQ,CAACG,WAAW;YAAC;YACrDtG,MAAMhD,IAAIgD,IAAI;YACd3C,OAAO+I;QACT;QACA,IAAI,CAAE,MAAM,IAAI,CAACK,iBAAiB,CAACD,YAAYvJ,MAAO;YACpD,yFAAyF;YACzF;QACF;QACA,IAAI;YACF,MAAM,IAAI,CAACO,YAAY,CAAC2I,QAAQ,CAACnJ,IAAIgD,IAAI,EAAEhD,IAAIK,KAAK,EAAE+I,UAAUpJ,IAAIsB,GAAG,CAAC6H,QAAQ,CAACO,MAAM,EAAE1J,IAAIsB,GAAG,CAAC6H,QAAQ,CAACQ,SAAS,EAAE,OAAO;gBAC1H1G,OAAOjD,IAAIsB,GAAG,CAAC2B,KAAK;gBACpB6D,YAAYC,IAAAA,0BAAgB,EAAC/G,IAAIsB,GAAG,CAAC0F,SAAS;YAChD;QACF,EAAE,OAAOpG,GAAG;YACV,OAAO,IAAI,CAACC,WAAW,CAACb,KAAKC,KAAKW,GAAGwI,SAAShH,GAAG;QACnD;QACA,OAAOnC,IAAIe,MAAM,CAACuI,aAAatI,kBAAU,CAACuD,UAAU,GAAGvD,kBAAU,CAACyC,OAAO,EAAEvC,IAAI;IACjF;IAEA,MAAgBsI,kBAAkBzJ,GAAsB,EAAEC,GAAiB,EAAoB;QAC7F,IAAI,CAACD,IAAIsB,GAAG,CAAC0F,SAAS,EAAE,OAAO;QAC/B,MAAMO,SAAmB,EAAE;QAC3B,IAAIqC,WAAW;QACf,IAAIC;QACJ,IAAIC,YAAYxD;QAChB,IAAIyD,WAAWzD,UAAU,iDAAiD;;QAC1E,IAAI0D,eAAe;QAEnB,KAAK,MAAMC,aAAajK,IAAIsB,GAAG,CAAC0F,SAAS,CAAE;YACzC,IAAIiD,UAAUnI,IAAI,EAAE;gBAClB,IAAImI,UAAUnI,IAAI,KAAK8H,UAAU;oBAC/BA,WAAWK,UAAUnI,IAAI;oBACzB+H,eAAe,MAAM,IAAI,CAACjE,aAAa,CAACyD,QAAQ,CAACrJ,IAAIgD,IAAI,EAAE4G;gBAC7D;gBACA,8CAA8C;gBAC9C,IAAI,CAACC,cAAc;oBACjB,IAAI,CAAC/I,MAAM,CAACC,IAAI,CAAC,CAAC,2BAA2B,EAAEkJ,UAAUnI,IAAI,CAAC,CAAC,CAAC;oBAChE,OAAO;gBACT;YACF,OAAO;gBACL8H,WAAW5J,IAAIsB,GAAG,CAACc,GAAG;gBACtByH,eAAe7J,IAAIK,KAAK;YAC1B;YAEA,IAAI4J,UAAUC,QAAQ,EAAE;gBACtB,IAAI;oBACF,MAAMrI,SAASsI,IAAAA,sBAAe,EAACnK,IAAIgD,IAAI,CAACb,EAAE,EAAE0H;oBAC5C,MAAMO,QAAQ,CAAC,CAAC,AAAC,CAAA,MAAM,IAAI,CAACtH,gBAAgB,CAACuH,cAAc,CAACxI,OAAM,EAAGyG,MAAM;oBAC3E,IAAI2B,UAAUC,QAAQ,CAACI,SAAS,KAAKF,OAAO;wBAC1C7C,OAAOhB,IAAI,CAAC,CAAC,8BAA8B,EAAE0D,UAAUC,QAAQ,CAACI,SAAS,CAAC,IAAI,EAAEF,MAAM,CAAC,CAAC;wBACxF;oBACF;gBACF,EAAE,OAAOxJ,GAAG;oBACV2G,OAAOhB,IAAI,CAAC,CAAC,+BAA+B,EAAE3F,EAAE2J,OAAO,EAAE;oBACzD;gBACF;YACF;YAEA,IAAIN,UAAU7F,KAAK,EAAE;gBACnB,MAAMA,QAAQ,MAAM,IAAI,CAACtB,gBAAgB,CAAC0H,cAAc,CAACP,UAAU7F,KAAK,CAAC8D,KAAK;gBAC9E,MAAMkC,QAAQhG,SAASwF,SAASa,UAAU,CAACrG,MAAM7B,OAAO,EAAEC;gBAC1D,IAAIyH,UAAU7F,KAAK,CAACkG,SAAS,KAAKF,OAAO;oBACvC,IAAI,CAAChG,OAAO;wBACVmD,OAAOhB,IAAI,CAAC,CAAC,oBAAoB,CAAC;oBACpC,OAAO;wBACLgB,OAAOhB,IAAI,CAAC,CAAC,yBAAyB,EAAEqD,SAAS,mBAAmB,EAAExF,MAAM7B,OAAO,EAAEC,SAAS,CAAC,CAAC;oBAClG;oBACA;gBACF;YACF;YAEA,IAAIyH,UAAUS,IAAI,EAAE;gBAClB,IAAIX,aAAazD,WAAW;oBAC1B,IAAIwD,cAAcxD,WAAW;wBAC3BwD,YAAY,AAAC,MAAMrI,IAAAA,mBAAY,EAACzB,IAAIK,KAAK,CAACqB,QAAQ,IAAK1B,IAAIK,KAAK,CAACqB,QAAQ,GAAG;oBAC9E;oBACAqI,WAAWD,YAAY7C,IAAAA,cAAO,EAAC,MAAM6C,aAAa;gBACpD;gBACA,MAAMM,QAAQL,aAAaE,UAAUS,IAAI,CAACxC,KAAK;gBAC/C,IAAI+B,UAAUS,IAAI,CAACJ,SAAS,KAAKF,OAAO;oBACtC7C,OAAOhB,IAAI,CAAC,CAAC,eAAe,EAAE0D,UAAUS,IAAI,CAACxC,KAAK,CAAC,IAAI,EAAE6B,SAAS,CAAC,CAAC;oBACpE;gBACF;YACF;YAEAC,eAAe;YACf;QACF;QAEA,IAAI,CAACA,cAAc;YACjB,IAAI,CAAClJ,MAAM,CAACC,IAAI,CAAC,CAAC,6BAA6B,EAAEwG,OAAOoD,IAAI,CAAC,OAAO;YACpE1K,IAAIe,MAAM,CAACC,kBAAU,CAAC2J,mBAAmB,EAAEzJ,IAAI,CAAC;QAClD;QACA,OAAO6I;IACT;IAEA,MAAcpI,YAAY5B,GAAsB,EAAEC,GAAiB,EAAE+D,UAAkB,EAAE;QACvF,IAAIhE,IAAIsB,GAAG,EAAE0F,WAAWsB,WAAW,GAAG;YACpC,IAAI,CAACxH,MAAM,CAACC,IAAI,CAAC;YACjB,OAAOd,IAAIe,MAAM,CAACC,kBAAU,CAACU,WAAW,EAAER,IAAI,CAAC;QACjD;QAEA,IAAIiD;QACJ,IAAI;YACFA,QAAQyG,IAAAA,yBAAe,EAAC7K,IAAIsB,GAAG,CAAC0F,SAAS;QAC3C,EAAE,OAAOpG,GAAG;YACV,IAAI,CAACE,MAAM,CAACC,IAAI,CAAC,GAAG,IAAI,CAACa,WAAW,CAACwE,IAAI,CAAC,6BAA6B,EAAE0E,KAAKC,SAAS,CAAC/K,IAAIsB,GAAG,CAAC0F,SAAS,EAAE,EAAE,EAAEpG,EAAE,CAAC,CAAC;YACnH,OAAOX,IAAIe,MAAM,CAACC,kBAAU,CAACU,WAAW,EAAER,IAAI,CAAC;QACjD;QAEA,MAAMC,OAAO,MAAM,IAAI,CAAC0B,gBAAgB,CAACqB,iBAAiB,CAACC,OAAOJ;QAClE,IAAI,CAAC5C,MAAM;YACT,IAAI,CAACN,MAAM,CAACC,IAAI,CAAC,CAAC,6CAA6C,EAAEqD,OAAO;YACxE,OAAOR,IAAAA,sBAAa,EAAC3C,kBAAU,CAAC2J,mBAAmB,EAAE9G,oBAAY,CAACO,mBAAmB,EAAEpE;QACzF;QACA,IAAImB,KAAKuB,KAAK,CAACR,EAAE,KAAKnC,IAAIgD,IAAI,CAACb,EAAE,EAAE;YACjC,IAAI,CAACrB,MAAM,CAACC,IAAI,CAAC,CAAC,kCAAkC,EAAEK,KAAKuB,KAAK,CAACqI,KAAK,CAAC,IAAI,EAAEhL,IAAIgD,IAAI,CAACgI,KAAK,EAAE;YAC7F,OAAO/K,IAAIe,MAAM,CAACC,kBAAU,CAACC,SAAS,EAAEC,IAAI,CAAC;QAC/C;QAEA,MAAM,IAAI,CAAC2B,gBAAgB,CAACmI,kBAAkB,CAAC7J,MAAMpB,IAAIsB,GAAG,CAACF,IAAI,CAAC8B,OAAO;QACzE,MAAME,WAAWC,IAAAA,kBAAS,EAAC;YAACjC;SAAK;QACjC,OAAOnB,IAAIsD,IAAI,CAACC,wBAAgB,EAAExC,MAAM,CAACC,kBAAU,CAACwC,EAAE,EAAEtC,IAAI,CAACwC,IAAAA,aAAQ,EAACP;IACxE;IAEQvC,YAAYb,GAAsB,EAAEC,GAAiB,EAAEW,CAAM,EAAEsK,KAAc,EAAE;QACrF,IAAI,CAACpK,MAAM,CAACiI,KAAK,CAAC,CAAC,UAAU,EAAE/I,IAAImL,MAAM,CAAC,CAAC,EAAEnL,IAAIsB,GAAG,CAACc,GAAG,GAAG8I,QAAQ,CAAC,IAAI,EAAEA,OAAO,GAAG,GAAG,GAAG,EAAEtK,EAAE2J,OAAO,EAAE;QACvG,IAAI3J,aAAawK,2BAAY,EAAE;YAC7B,OAAOxH,IAAAA,sBAAa,EAAC3C,kBAAU,CAAC4C,MAAM,EAAEC,oBAAY,CAACC,aAAa,EAAE9D,KAAKW,EAAEQ,IAAI,CAACmB,OAAO,EAAEC,YAAY5B,EAAEQ,IAAI,CAAC4C,UAAU;QACxH,OAAO,IAAIpD,aAAayK,oBAAS,EAAE;YACjC,OAAOpL,IAAIe,MAAM,CAACJ,EAAE0K,QAAQ,EAAEnK,IAAI,CAACP,EAAE2J,OAAO;QAC9C;QACA,MAAM,IAAIgB,qBAAa,CAAC3K,EAAE2J,OAAO,EAAEtJ,kBAAU,CAACuK,qBAAqB;IACrE;IA5aA,YACE,AAAiB5F,aAA2B,EAC5C,AAAiBpF,YAA0B,EAC3C,AAAiBsC,gBAAkC,CACnD;aAHiB8C,gBAAAA;aACApF,eAAAA;aACAsC,mBAAAA;aALFhC,SAAS,IAAI2K,cAAM,CAAC3L,cAAcsG,IAAI;IAMpD;AAyaL"}
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/webdav/services/webdav-methods.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 } from 'fastify'\nimport { currentTimeStamp, encodeUrl } from '../../../common/shared'\nimport { FileLock } from '../../files/interfaces/file-lock.interface'\nimport { FileError } from '../../files/models/file-error'\nimport { LockConflict } from '../../files/models/file-lock-error'\nimport { FilesLockManager } from '../../files/services/files-lock-manager.service'\nimport { FilesManager } from '../../files/services/files-manager.service'\nimport { dirName, genEtag, isPathExists } from '../../files/utils/files'\nimport { SPACE_OPERATION, SPACE_REPOSITORY } from '../../spaces/constants/spaces'\nimport { SpaceEnv } from '../../spaces/models/space-env.model'\nimport { dbFileFromSpace } from '../../spaces/utils/paths'\nimport { haveSpaceEnvPermissions } from '../../spaces/utils/permissions'\nimport {\n DEPTH,\n LOCK_DISCOVERY_PROP,\n NS_PREFIX,\n PRECONDITION,\n PROPPATCH_METHOD,\n PROPPATCH_MODIFIED_PROPS,\n PROPPATCH_PROP_UPDATE,\n PROPPATCH_SUPPORTED_PROPS,\n PROPSTAT,\n STANDARD_PROPS,\n XML_CONTENT_TYPE\n} from '../constants/webdav'\nimport { IfHeaderDecorator } from '../decorators/if-header.decorator'\nimport { FastifyDAVRequest, WebDAVLock } from '../interfaces/webdav.interface'\nimport { extractAllTokens, extractOneToken } from '../utils/if-header'\nimport { DAV_ERROR_RES, LOCK_DISCOVERY, LOCK_PROP, MULTI_STATUS, PROP, PROP_STAT } from '../utils/webdav'\nimport { xmlBuild } from '../utils/xml'\nimport { WebDAVSpaces } from './webdav-spaces.service'\n\n@Injectable()\nexport class WebDAVMethods {\n private readonly logger = new Logger(WebDAVMethods.name)\n\n constructor(\n private readonly webDAVHandler: WebDAVSpaces,\n private readonly filesManager: FilesManager,\n private readonly filesLockManager: FilesLockManager\n ) {}\n\n async headOrGet(req: FastifyDAVRequest, res: FastifyReply, repository: string): Promise<StreamableFile> {\n if (repository === SPACE_REPOSITORY.FILES && !req.space.inSharesList) {\n const sendFile = this.filesManager.sendFileFromSpace(req.space)\n try {\n await sendFile.checks()\n return await sendFile.stream(req, res)\n } catch (e) {\n return this.handleError(req, res, e)\n }\n }\n this.logger.warn(`Not allowed on this resource : ${repository}`)\n return res.status(HttpStatus.FORBIDDEN).send('Not allowed on this resource')\n }\n\n @IfHeaderDecorator()\n async lock(req: FastifyDAVRequest, res: FastifyReply) {\n const isLockRefresh = !req.dav.body\n const rExists = await isPathExists(req.space.realPath)\n\n if (isLockRefresh) {\n // if the body has no content, the request must refresh the lock\n if (!rExists) {\n this.logger.warn('Lock refresh must specify an existing resource')\n return res.status(HttpStatus.BAD_REQUEST).send('Lock refresh must specify an existing resource')\n }\n return this.lockRefresh(req, res, req.space.dbFile.path)\n }\n if (!rExists) {\n if (!haveSpaceEnvPermissions(req.space, SPACE_OPERATION.ADD)) {\n this.logger.warn(`is not allowed to create on this space : *${req.space.alias}* (${req.space.id}) : ${req.space.url}`)\n return res.status(HttpStatus.FORBIDDEN).send('You are not allowed to do this action')\n }\n if (!(await isPathExists(dirName(req.space.realPath)))) {\n return res.status(HttpStatus.CONFLICT).send('Parent must exists')\n }\n }\n\n const davLock: WebDAVLock = {\n lockroot: req.dav.url,\n locktoken: null, // created later\n lockscope: req.dav.lock.lockscope,\n owner: req.dav.lock.owner\n }\n\n const [ok, fileLock] = await this.filesLockManager.create(req.user, req.space.dbFile, req.dav.depth, req.dav.lock.timeout, davLock)\n if (ok) {\n // Locking unmapped URLs: must create an empty resource (that is not a collection)\n if (!rExists) {\n // checkLocks set to false because the conflicts are already checked in `filesLockManager.create` method\n await this.filesManager.mkFile(req.user, req.space, false, false, false)\n }\n const lockProp = LOCK_PROP([fileLock])\n return res\n .header('lock-token', `<${davLock.locktoken}>`)\n .type(XML_CONTENT_TYPE)\n .status(rExists ? HttpStatus.OK : HttpStatus.CREATED)\n .send(xmlBuild(lockProp))\n } else {\n return DAV_ERROR_RES(HttpStatus.LOCKED, PRECONDITION.LOCK_CONFLICT, res, fileLock.davLock?.lockroot || fileLock.dbFilePath)\n }\n }\n\n @IfHeaderDecorator()\n async unlock(req: FastifyDAVRequest, res: FastifyReply) {\n if (!(await isPathExists(req.space.realPath))) {\n this.logger.warn(`Unable to unlock ${req.dav.url} : resource does not exist`)\n return res.status(HttpStatus.NOT_FOUND).send(req.dav.url)\n }\n\n const lock = await this.filesLockManager.isLockedWithToken(req.dav.lock.token, req.space.dbFile.path)\n if (!lock) {\n this.logger.warn(`Lock token does not exist or not match URL : ${req.dav.lock.token}`)\n return DAV_ERROR_RES(HttpStatus.CONFLICT, PRECONDITION.LOCK_TOKEN_MISMATCH, res)\n }\n if (req.user.id !== lock.owner.id) {\n return res.status(HttpStatus.FORBIDDEN).send('Token was created by another user')\n }\n\n await this.filesLockManager.removeLock(lock.key)\n return res.status(HttpStatus.NO_CONTENT).send()\n }\n\n @IfHeaderDecorator()\n async propfind(req: FastifyDAVRequest, res: FastifyReply, repository: string): Promise<string> {\n if (repository === SPACE_REPOSITORY.FILES && !req.space.inSharesList) {\n if (!(await isPathExists(req.space.realPath))) {\n return res.status(HttpStatus.NOT_FOUND).send(req.dav.url)\n }\n }\n\n const responses: any[] = []\n let requestedProps: string[]\n let locks: Record<string, FileLock> = {}\n\n if (req.dav.propfindMode === PROPSTAT.PROP) {\n // ignores all unknown properties (non-RFC compliant but avoids generating too much content, faster)\n requestedProps = Object.keys(req.dav.body.propfind.prop).filter((prop: string) => STANDARD_PROPS.indexOf(prop) > -1)\n } else {\n requestedProps = STANDARD_PROPS\n }\n\n // Searches all child locks (only for real files) & ignores /webdav/shares endpoint (special case)\n if (req.dav.propfindMode !== PROPSTAT.PROPNAME && repository === SPACE_REPOSITORY.FILES && !req.space.inSharesList) {\n if (req.dav.depth === DEPTH.RESOURCE) {\n // match depth '0'\n locks = await this.filesLockManager.browseLocks(req.space.dbFile)\n } else {\n // match depth '1' or 'infinity'\n locks = await this.filesLockManager.browseParentChildLocks(req.space.dbFile)\n }\n }\n\n for await (const f of this.webDAVHandler.propfind(req, repository)) {\n let prop: any\n if (req.dav.propfindMode === PROPSTAT.PROPNAME) {\n prop = { ...Object.fromEntries(requestedProps.map((x) => [`${NS_PREFIX}:${x}`, ''])) }\n } else {\n prop = {}\n for (const p of requestedProps) {\n let fP: any\n if (p === LOCK_DISCOVERY_PROP) {\n fP = repository === SPACE_REPOSITORY.FILES && f.name in locks ? LOCK_DISCOVERY([locks[f.name]]) : null\n } else {\n fP = f[p]\n }\n if (fP !== undefined) prop[`${NS_PREFIX}:${p}`] = fP\n }\n }\n responses.push(PROP_STAT(f.href, PROP(prop, req.dav.httpVersion, HttpStatus.OK)))\n }\n const propfind = xmlBuild(MULTI_STATUS(responses))\n return res.type(XML_CONTENT_TYPE).status(HttpStatus.MULTI_STATUS).send(propfind)\n }\n\n @IfHeaderDecorator()\n async put(req: FastifyDAVRequest, res: FastifyReply): Promise<FastifyReply> {\n let rExists: boolean\n try {\n rExists = await this.filesManager.saveStream(req.user, req.space, req, {\n dav: {\n depth: req.dav.depth,\n lockTokens: extractAllTokens(req.dav.ifHeaders)\n }\n })\n } catch (e) {\n return this.handleError(req, res, e)\n }\n return res\n .header('etag', genEtag(null, req.space.realPath))\n .status(rExists ? HttpStatus.NO_CONTENT : HttpStatus.CREATED)\n .send()\n }\n\n @IfHeaderDecorator()\n async delete(req: FastifyDAVRequest, res: FastifyReply) {\n try {\n await this.filesManager.delete(req.user, req.space, { lockTokens: extractAllTokens(req.dav.ifHeaders) })\n } catch (e) {\n return this.handleError(req, res, e)\n }\n return res.status(HttpStatus.NO_CONTENT).send()\n }\n\n @IfHeaderDecorator()\n async proppatch(req: FastifyDAVRequest, res: FastifyReply) {\n /* only support 'time modifications' */\n if (!(await isPathExists(req.space.realPath))) {\n return res.status(HttpStatus.NOT_FOUND).send(req.dav.url)\n }\n\n // check locks\n try {\n await this.filesLockManager.checkConflicts(req.space.dbFile, req.dav.depth, {\n userId: req.user.id,\n lockTokens: extractAllTokens(req.dav.ifHeaders)\n })\n } catch (e) {\n return this.handleError(req, res, e)\n }\n\n // evaluate props and return multistatus if errors\n req.dav.proppatch = { props: {}, errors: [] }\n for (const action of Object.keys(req.dav.body[PROPPATCH_PROP_UPDATE])) {\n if (Object.values(PROPPATCH_METHOD).indexOf(action) === -1) {\n const msg = `Unknown tag : expected ${PROPPATCH_METHOD.SET} or ${PROPPATCH_METHOD.REMOVE}`\n this.logger.debug(msg)\n return res.status(HttpStatus.BAD_REQUEST).send(msg)\n }\n\n if (Array.isArray(req.dav.body[PROPPATCH_PROP_UPDATE][action])) {\n if (Object.keys(req.dav.body[PROPPATCH_PROP_UPDATE][action][0])[0] === PROPSTAT.PROP) {\n req.dav.body[PROPPATCH_PROP_UPDATE][action] = {\n [PROPSTAT.PROP]: req.dav.body[PROPPATCH_PROP_UPDATE][action].map((e: any) => e[PROPSTAT.PROP])\n }\n }\n }\n\n if (Object.keys(req.dav.body[PROPPATCH_PROP_UPDATE][action])[0] !== PROPSTAT.PROP) {\n const msg = `Unknown tag : expected ${PROPSTAT.PROP}`\n this.logger.debug(msg)\n return res.status(HttpStatus.BAD_REQUEST).send(msg)\n }\n\n if (!Array.isArray(req.dav.body[PROPPATCH_PROP_UPDATE][action][PROPSTAT.PROP])) {\n req.dav.body[PROPPATCH_PROP_UPDATE][action][PROPSTAT.PROP] = [req.dav.body[PROPPATCH_PROP_UPDATE][action][PROPSTAT.PROP]]\n }\n\n for (const prop of req.dav.body[PROPPATCH_PROP_UPDATE][action][PROPSTAT.PROP] as Record<string, string>[]) {\n for (let [name, value] of Object.entries(prop)) {\n if (action === PROPPATCH_METHOD.REMOVE) {\n value = null\n this.logger.debug(`Proppatch remove method not handled : ${name} -> ${value}`)\n }\n if (PROPPATCH_SUPPORTED_PROPS.indexOf(name) === -1) {\n req.dav.proppatch.errors.push(\n PROP(\n { [`${NS_PREFIX}:${name}`]: null },\n req.dav.httpVersion,\n HttpStatus.FORBIDDEN,\n STANDARD_PROPS.indexOf(name) > -1 ? PRECONDITION.PROTECTED_PROPERTY : undefined\n )\n )\n continue\n }\n req.dav.proppatch.props[name] = value\n }\n }\n }\n\n if (req.dav.proppatch.errors.length) {\n // convert all passed props to failed dependency\n for (const name of Object.keys(req.dav.proppatch.props)) {\n req.dav.proppatch.errors.push(PROP({ [`${NS_PREFIX}:${name}`]: null }, req.dav.httpVersion, HttpStatus.FAILED_DEPENDENCY))\n }\n const proppatch = xmlBuild(MULTI_STATUS(PROP_STAT(encodeUrl(req.dav.url), req.dav.proppatch.errors)))\n return res.status(HttpStatus.MULTI_STATUS).type(XML_CONTENT_TYPE).send(proppatch)\n }\n\n // apply modifications\n let atLeastOneError = false\n const states: Record<string, boolean> = {}\n for (const [name, value] of Object.entries(req.dav.proppatch.props)) {\n if (PROPPATCH_MODIFIED_PROPS.indexOf(name) > -1) {\n try {\n await this.filesManager.touch(req.user, req.space, currentTimeStamp(new Date(value)), false)\n } catch (e) {\n this.logger.error(`${this.proppatch.name} - unable to modify mtime on ${req.dav.url} : ${e}`)\n states[name] = false\n atLeastOneError = true\n }\n }\n // hook: we let the known Win32* properties pass to return a consistent result\n states[name] = true\n }\n\n const props = []\n for (const [name, state] of Object.entries(states)) {\n props.push(\n PROP(\n { [`${NS_PREFIX}:${name}`]: null },\n req.dav.httpVersion,\n state ? (atLeastOneError ? HttpStatus.FAILED_DEPENDENCY : HttpStatus.OK) : HttpStatus.BAD_REQUEST\n )\n )\n }\n const proppatch = xmlBuild(MULTI_STATUS(PROP_STAT(encodeUrl(req.dav.url), props)))\n return res.type(XML_CONTENT_TYPE).status(HttpStatus.MULTI_STATUS).send(proppatch)\n }\n\n @IfHeaderDecorator()\n async mkcol(req: FastifyDAVRequest, res: FastifyReply) {\n try {\n await this.filesManager.mkDir(req.user, req.space, false, { depth: req.dav.depth, lockTokens: extractAllTokens(req.dav.ifHeaders) })\n } catch (e) {\n return this.handleError(req, res, e)\n }\n return res.status(HttpStatus.CREATED).send()\n }\n\n @IfHeaderDecorator()\n async copyMove(req: FastifyDAVRequest, res: FastifyReply) {\n const dstSpace: SpaceEnv = await this.webDAVHandler.spaceEnv(req.user, req.dav.copyMove.destination)\n if (!dstSpace) {\n this.logger.warn(`Space not found for destination : ${req.dav.copyMove.destination}`)\n return res.status(HttpStatus.NOT_FOUND).send(req.dav.copyMove.destination)\n }\n const dstExisted = await isPathExists(dstSpace.realPath)\n // We must evaluate the if-headers on the destination\n const fakeDstReq = {\n dav: { ...req.dav, url: req.dav.copyMove.destination },\n user: req.user,\n space: dstSpace\n } as FastifyDAVRequest\n if (!(await this.evaluateIfHeaders(fakeDstReq, res))) {\n // if there is an error the response is generated inside the `evaluateIfHeaders` function\n return\n }\n try {\n await this.filesManager.copyMove(req.user, req.space, dstSpace, req.dav.copyMove.isMove, req.dav.copyMove.overwrite, false, {\n depth: req.dav.depth,\n lockTokens: extractAllTokens(req.dav.ifHeaders)\n })\n } catch (e) {\n return this.handleError(req, res, e, dstSpace.url)\n }\n return res.status(dstExisted ? HttpStatus.NO_CONTENT : HttpStatus.CREATED).send()\n }\n\n protected async evaluateIfHeaders(req: FastifyDAVRequest, res: FastifyReply): Promise<boolean> {\n if (!req.dav.ifHeaders) return true\n const errors: string[] = []\n let lastPath = null\n let lastSpaceEnv: SpaceEnv\n let lastRPath = undefined\n let lastEtag = undefined // for now, we only generate one etag type (weak)\n let atLeastOneOk = false\n\n for (const condition of req.dav.ifHeaders) {\n if (condition.path) {\n if (condition.path !== lastPath) {\n lastPath = condition.path\n lastSpaceEnv = await this.webDAVHandler.spaceEnv(req.user, lastPath)\n }\n // the path will be the same across conditions\n if (!lastSpaceEnv) {\n this.logger.warn(`If Header : path mismatch (${condition.path})`)\n return false\n }\n } else {\n lastPath = req.dav.url\n lastSpaceEnv = req.space\n }\n\n if (condition.haveLock) {\n try {\n const dbFile = dbFileFromSpace(req.user.id, lastSpaceEnv)\n const match = !!(await this.filesLockManager.getLocksByPath(dbFile)).length\n if (condition.haveLock.mustMatch !== match) {\n errors.push(`have lock condition mismatch (${condition.haveLock.mustMatch} != ${match})`)\n continue\n }\n } catch (e) {\n errors.push(`have lock condition mismatch : ${e.message}`)\n continue\n }\n }\n\n if (condition.token) {\n const token = await this.filesLockManager.getLockByToken(condition.token.value)\n const match = token && lastPath.startsWith(token.davLock?.lockroot)\n if (condition.token.mustMatch !== match) {\n if (!token) {\n errors.push(`lock token not found`)\n } else {\n errors.push(`lock token url mismatch (${lastPath} is not a child of ${token.davLock?.lockroot})`)\n }\n continue\n }\n }\n\n if (condition.etag) {\n if (lastEtag === undefined) {\n if (lastRPath === undefined) {\n lastRPath = (await isPathExists(req.space.realPath)) ? req.space.realPath : null\n }\n lastEtag = lastRPath ? genEtag(null, lastRPath) : null\n }\n const match = lastEtag === condition.etag.value\n if (condition.etag.mustMatch !== match) {\n errors.push(`etag mismatch (${condition.etag.value} != ${lastEtag})`)\n continue\n }\n }\n\n atLeastOneOk = true\n break\n }\n\n if (!atLeastOneOk) {\n this.logger.warn(`If header condition failed : ${errors.join(', ')}`)\n res.status(HttpStatus.PRECONDITION_FAILED).send('If header condition failed')\n }\n return atLeastOneOk\n }\n\n private async lockRefresh(req: FastifyDAVRequest, res: FastifyReply, dbFilePath: string) {\n if (req.dav?.ifHeaders?.length !== 1) {\n this.logger.warn('Expected a lock token (only one lock may be refreshed at a time)')\n return res.status(HttpStatus.BAD_REQUEST).send('Expected a lock token (only one lock may be refreshed at a time)')\n }\n\n let token: string\n try {\n token = extractOneToken(req.dav.ifHeaders)\n } catch (e) {\n this.logger.warn(`${this.lockRefresh.name} - unable to extract token : ${JSON.stringify(req.dav.ifHeaders)} (${e})`)\n return res.status(HttpStatus.BAD_REQUEST).send('Unable to extract token')\n }\n\n const lock = await this.filesLockManager.isLockedWithToken(token, dbFilePath)\n if (!lock) {\n this.logger.warn(`Lock token does not exist or not match URL : ${token}`)\n return DAV_ERROR_RES(HttpStatus.PRECONDITION_FAILED, PRECONDITION.LOCK_TOKEN_MISMATCH, res)\n }\n if (lock.owner.id !== req.user.id) {\n this.logger.warn(`Lock token does not match owner : ${lock.owner.login} != ${req.user.login}`)\n return res.status(HttpStatus.FORBIDDEN).send('Lock token does not match owner')\n }\n\n await this.filesLockManager.refreshLockTimeout(lock, req.dav.lock.timeout)\n const lockProp = LOCK_PROP([lock])\n return res.type(XML_CONTENT_TYPE).status(HttpStatus.OK).send(xmlBuild(lockProp))\n }\n\n private handleError(req: FastifyDAVRequest, res: FastifyReply, e: any, toUrl?: string) {\n this.logger.error(`Unable to ${req.method} ${req.dav.url}${toUrl ? ` -> ${toUrl}` : ''} : ${e.message}`)\n const errorMsg = e.message.split(',')[0]\n if (e instanceof LockConflict) {\n return DAV_ERROR_RES(HttpStatus.LOCKED, PRECONDITION.LOCK_CONFLICT, res, e.lock.davLock?.lockroot || e.lock.dbFilePath)\n } else if (e instanceof FileError) {\n return res.status(e.httpCode).send(errorMsg)\n }\n throw new HttpException(errorMsg, HttpStatus.INTERNAL_SERVER_ERROR)\n }\n}\n"],"names":["WebDAVMethods","headOrGet","req","res","repository","SPACE_REPOSITORY","FILES","space","inSharesList","sendFile","filesManager","sendFileFromSpace","checks","stream","e","handleError","logger","warn","status","HttpStatus","FORBIDDEN","send","lock","isLockRefresh","dav","body","rExists","isPathExists","realPath","BAD_REQUEST","lockRefresh","dbFile","path","haveSpaceEnvPermissions","SPACE_OPERATION","ADD","alias","id","url","dirName","CONFLICT","davLock","lockroot","locktoken","lockscope","owner","ok","fileLock","filesLockManager","create","user","depth","timeout","mkFile","lockProp","LOCK_PROP","header","type","XML_CONTENT_TYPE","OK","CREATED","xmlBuild","DAV_ERROR_RES","LOCKED","PRECONDITION","LOCK_CONFLICT","dbFilePath","unlock","NOT_FOUND","isLockedWithToken","token","LOCK_TOKEN_MISMATCH","removeLock","key","NO_CONTENT","propfind","responses","requestedProps","locks","propfindMode","PROPSTAT","PROP","Object","keys","prop","filter","STANDARD_PROPS","indexOf","PROPNAME","DEPTH","RESOURCE","browseLocks","browseParentChildLocks","f","webDAVHandler","fromEntries","map","x","NS_PREFIX","p","fP","LOCK_DISCOVERY_PROP","name","LOCK_DISCOVERY","undefined","push","PROP_STAT","href","httpVersion","MULTI_STATUS","put","saveStream","lockTokens","extractAllTokens","ifHeaders","genEtag","delete","proppatch","checkConflicts","userId","props","errors","action","PROPPATCH_PROP_UPDATE","values","PROPPATCH_METHOD","msg","SET","REMOVE","debug","Array","isArray","value","entries","PROPPATCH_SUPPORTED_PROPS","PROTECTED_PROPERTY","length","FAILED_DEPENDENCY","encodeUrl","atLeastOneError","states","PROPPATCH_MODIFIED_PROPS","touch","currentTimeStamp","Date","error","state","mkcol","mkDir","copyMove","dstSpace","spaceEnv","destination","dstExisted","fakeDstReq","evaluateIfHeaders","isMove","overwrite","lastPath","lastSpaceEnv","lastRPath","lastEtag","atLeastOneOk","condition","haveLock","dbFileFromSpace","match","getLocksByPath","mustMatch","message","getLockByToken","startsWith","etag","join","PRECONDITION_FAILED","extractOneToken","JSON","stringify","login","refreshLockTimeout","toUrl","method","errorMsg","split","LockConflict","FileError","httpCode","HttpException","INTERNAL_SERVER_ERROR","Logger"],"mappings":"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"}
|
|
@@ -48,7 +48,6 @@ _export(exports, {
|
|
|
48
48
|
}
|
|
49
49
|
});
|
|
50
50
|
const _nodehttp = /*#__PURE__*/ _interop_require_default(require("node:http"));
|
|
51
|
-
const _appconstants = require("../../../app.constants");
|
|
52
51
|
const _shared = require("../../../common/shared");
|
|
53
52
|
const _webdav = require("../constants/webdav");
|
|
54
53
|
const _xml = require("./xml");
|
|
@@ -127,7 +126,7 @@ function LOCK_DISCOVERY(locks) {
|
|
|
127
126
|
[`${_webdav.NS_PREFIX}:${lock.davLock?.lockscope || _webdav.LOCK_SCOPE.EXCLUSIVE}`]: null
|
|
128
127
|
},
|
|
129
128
|
[`${_webdav.NS_PREFIX}:locktoken`]: {
|
|
130
|
-
[`${_webdav.NS_PREFIX}:href`]: lock.davLock?.locktoken ||
|
|
129
|
+
[`${_webdav.NS_PREFIX}:href`]: lock.davLock?.locktoken || _shared.SERVER_NAME
|
|
131
130
|
},
|
|
132
131
|
[`${_webdav.NS_PREFIX}:lockroot`]: {
|
|
133
132
|
[`${_webdav.NS_PREFIX}:href`]: (0, _shared.encodeUrl)(lock.davLock?.lockroot || lock.dbFilePath)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/webdav/utils/webdav.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 { FastifyReply } from 'fastify'\nimport http from 'node:http'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/webdav/utils/webdav.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 { FastifyReply } from 'fastify'\nimport http from 'node:http'\nimport { currentTimeStamp, encodeUrl, SERVER_NAME } from '../../../common/shared'\nimport { FileLock } from '../../files/interfaces/file-lock.interface'\nimport { LOCK_SCOPE, NS_DAV, NS_PREFIX, PROPSTAT, XML_CONTENT_TYPE } from '../constants/webdav'\nimport { XML_NS, xmlBuild } from './xml'\n\nexport const XML_DAV_NS = { [`${XML_NS}:${NS_PREFIX}`]: `${NS_DAV}` }\nexport const PROPFIND_COLLECTION = { [`${NS_PREFIX}:collection`]: null }\nexport const PROPFIND_ALL_PROP = {\n [`${NS_PREFIX}:propfind`]: {\n [`${NS_PREFIX}:${PROPSTAT.ALLPROP}`]: null,\n ...XML_DAV_NS\n }\n}\n\nexport const SUPPORTED_LOCKS = {\n [`${NS_PREFIX}:lockentry`]: [\n {\n [`${NS_PREFIX}:lockscope`]: {\n [`${NS_PREFIX}:exclusive`]: null\n },\n [`${NS_PREFIX}:locktype`]: {\n [`${NS_PREFIX}:write`]: null\n }\n },\n {\n [`${NS_PREFIX}:lockscope`]: {\n [`${NS_PREFIX}:shared`]: null\n },\n [`${NS_PREFIX}:locktype`]: {\n [`${NS_PREFIX}:write`]: null\n }\n }\n ]\n}\n\nexport function PROP(prop: any, httpVersion: string, httpStatus: number, description?: string) {\n return {\n [`${NS_PREFIX}:prop`]: prop,\n [`${NS_PREFIX}:status`]: `${httpVersion} ${httpStatus} ${http.STATUS_CODES[httpStatus]}`,\n [`${NS_PREFIX}:responsedescription`]: description ? { [`${NS_PREFIX}:error`]: { [`${NS_PREFIX}:${description}`]: null } } : undefined\n }\n}\n\nexport function PROP_STAT(href: string, props: any) {\n return {\n [`${NS_PREFIX}:href`]: href,\n [`${NS_PREFIX}:propstat`]: props\n }\n}\n\nexport function MULTI_STATUS(content: any) {\n return {\n [`${NS_PREFIX}:multistatus`]: { [`${NS_PREFIX}:response`]: content, ...XML_DAV_NS }\n }\n}\n\nexport function LOCK_DISCOVERY(locks: FileLock[]) {\n // only locktype write is currently implemented in RFC\n const activeLocks = []\n for (const lock of locks) {\n activeLocks.push({\n [`${NS_PREFIX}:activelock`]: {\n [`${NS_PREFIX}:locktype`]: { [`${NS_PREFIX}:write`]: null },\n [`${NS_PREFIX}:lockscope`]: { [`${NS_PREFIX}:${lock.davLock?.lockscope || LOCK_SCOPE.EXCLUSIVE}`]: null },\n [`${NS_PREFIX}:locktoken`]: { [`${NS_PREFIX}:href`]: lock.davLock?.locktoken || SERVER_NAME },\n [`${NS_PREFIX}:lockroot`]: { [`${NS_PREFIX}:href`]: encodeUrl(lock.davLock?.lockroot || lock.dbFilePath) },\n [`${NS_PREFIX}:owner`]: lock.davLock?.owner || 'WebDAV',\n [`${NS_PREFIX}:timeout`]: `Second-${Math.floor(lock.expiration - currentTimeStamp())}`,\n [`${NS_PREFIX}:depth`]: lock.depth\n }\n })\n }\n return activeLocks\n}\n\nexport function LOCK_PROP(locks: FileLock[]) {\n return { [`${NS_PREFIX}:prop`]: { [`${NS_PREFIX}:lockdiscovery`]: LOCK_DISCOVERY(locks), ...XML_DAV_NS } }\n}\n\nexport function DAV_ERROR(error: string, href?: string): string {\n return xmlBuild({\n 'ns0:error': { [`ns0:${error}`]: href ? [{ 'ns0:href': encodeUrl(href) }] : '', [`${XML_NS}:ns0`]: `${NS_DAV}` }\n })\n}\n\nexport function DAV_ERROR_RES(code: number, error: string, res: FastifyReply, href?: string): FastifyReply {\n return res.status(code).type(XML_CONTENT_TYPE).send(DAV_ERROR(error, href))\n}\n"],"names":["DAV_ERROR","DAV_ERROR_RES","LOCK_DISCOVERY","LOCK_PROP","MULTI_STATUS","PROP","PROPFIND_ALL_PROP","PROPFIND_COLLECTION","PROP_STAT","SUPPORTED_LOCKS","XML_DAV_NS","XML_NS","NS_PREFIX","NS_DAV","PROPSTAT","ALLPROP","prop","httpVersion","httpStatus","description","http","STATUS_CODES","undefined","href","props","content","locks","activeLocks","lock","push","davLock","lockscope","LOCK_SCOPE","EXCLUSIVE","locktoken","SERVER_NAME","encodeUrl","lockroot","dbFilePath","owner","Math","floor","expiration","currentTimeStamp","depth","error","xmlBuild","code","res","status","type","XML_CONTENT_TYPE","send"],"mappings":"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"}
|
|
@@ -46,7 +46,7 @@ _export(exports, {
|
|
|
46
46
|
});
|
|
47
47
|
const _classtransformer = require("class-transformer");
|
|
48
48
|
const _classvalidator = require("class-validator");
|
|
49
|
-
const
|
|
49
|
+
const _shared = require("../common/shared");
|
|
50
50
|
const _auth = require("./constants/auth");
|
|
51
51
|
const _authldap = require("./constants/auth-ldap");
|
|
52
52
|
function _ts_decorate(decorators, target, key, desc) {
|
|
@@ -61,7 +61,7 @@ function _ts_metadata(k, v) {
|
|
|
61
61
|
let AuthMfaTotpConfig = class AuthMfaTotpConfig {
|
|
62
62
|
constructor(){
|
|
63
63
|
this.enabled = true;
|
|
64
|
-
this.issuer =
|
|
64
|
+
this.issuer = _shared.SERVER_NAME;
|
|
65
65
|
}
|
|
66
66
|
};
|
|
67
67
|
_ts_decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../backend/src/authentication/auth.config.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 { Exclude, Transform, Type } from 'class-transformer'\nimport {\n ArrayNotEmpty,\n IsArray,\n IsBoolean,\n IsDefined,\n IsEnum,\n IsIn,\n IsNotEmpty,\n IsNotEmptyObject,\n IsObject,\n IsOptional,\n IsString,\n ValidateIf,\n ValidateNested\n} from 'class-validator'\nimport { SERVER_NAME } from '../
|
|
1
|
+
{"version":3,"sources":["../../../backend/src/authentication/auth.config.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 { Exclude, Transform, Type } from 'class-transformer'\nimport {\n ArrayNotEmpty,\n IsArray,\n IsBoolean,\n IsDefined,\n IsEnum,\n IsIn,\n IsNotEmpty,\n IsNotEmptyObject,\n IsObject,\n IsOptional,\n IsString,\n ValidateIf,\n ValidateNested\n} from 'class-validator'\nimport { SERVER_NAME } from '../common/shared'\nimport { ACCESS_KEY, CSRF_KEY, REFRESH_KEY, WS_KEY } from './constants/auth'\nimport { LDAP_COMMON_ATTR, LDAP_LOGIN_ATTR } from './constants/auth-ldap'\n\nexport class AuthMfaTotpConfig {\n @IsBoolean()\n enabled = true\n\n @IsString()\n issuer = SERVER_NAME\n}\n\nexport class AuthMfaConfig {\n @IsDefined()\n @IsNotEmptyObject()\n @IsObject()\n @ValidateNested()\n @Type(() => AuthMfaTotpConfig)\n totp: AuthMfaTotpConfig = new AuthMfaTotpConfig()\n}\n\nexport class AuthTokenAccessConfig {\n @Exclude({ toClassOnly: true })\n // force default name\n name = ACCESS_KEY\n\n @IsString()\n @IsNotEmpty()\n secret: string\n\n @IsString()\n @IsNotEmpty()\n expiration = '30m'\n}\n\nexport class AuthTokenRefreshConfig {\n @Exclude({ toClassOnly: true })\n // force default name\n name = REFRESH_KEY\n\n @IsString()\n @IsNotEmpty()\n secret: string\n\n @IsString()\n @IsNotEmpty()\n expiration = '4h'\n}\n\nexport class AuthTokenCsrfConfig extends AuthTokenRefreshConfig {\n @IsString()\n @IsNotEmpty()\n override name: string = CSRF_KEY\n}\n\nexport class AuthTokenWSConfig extends AuthTokenRefreshConfig {\n @IsString()\n @IsNotEmpty()\n override name: string = WS_KEY\n}\n\nexport class AuthTokenConfig {\n @IsDefined()\n @IsNotEmptyObject()\n @IsObject()\n @ValidateNested()\n @Type(() => AuthTokenAccessConfig)\n access: AuthTokenAccessConfig\n\n @IsDefined()\n @IsNotEmptyObject()\n @IsObject()\n @ValidateNested()\n @Type(() => AuthTokenRefreshConfig)\n refresh: AuthTokenRefreshConfig\n\n @IsDefined()\n @IsNotEmptyObject()\n @IsObject()\n @ValidateNested()\n @Type(() => AuthTokenCsrfConfig)\n csrf: AuthTokenCsrfConfig\n\n @IsDefined()\n @IsNotEmptyObject()\n @IsObject()\n @ValidateNested()\n @Type(() => AuthTokenWSConfig)\n ws: AuthTokenWSConfig\n}\n\nexport class AuthMethodLdapAttributesConfig {\n @IsOptional()\n @IsString()\n @Transform(({ value }) => value || LDAP_LOGIN_ATTR.UID)\n @IsEnum(LDAP_LOGIN_ATTR)\n login: LDAP_LOGIN_ATTR = LDAP_LOGIN_ATTR.UID\n\n @IsOptional()\n @IsString()\n @Transform(({ value }) => value || LDAP_COMMON_ATTR.MAIL)\n email: string = LDAP_COMMON_ATTR.MAIL\n}\n\nexport class AuthMethodLdapConfig {\n @Transform(({ value }) => (Array.isArray(value) ? value.filter((v: string) => Boolean(v)) : value))\n @ArrayNotEmpty()\n @IsArray()\n @IsString({ each: true })\n servers: string[]\n\n @IsString()\n @IsNotEmpty()\n baseDN: string\n\n @IsOptional()\n @IsString()\n filter?: string\n\n @IsDefined()\n @IsNotEmptyObject()\n @IsObject()\n @ValidateNested()\n @Type(() => AuthMethodLdapAttributesConfig)\n attributes: AuthMethodLdapAttributesConfig = new AuthMethodLdapAttributesConfig()\n\n @IsOptional()\n @IsString()\n adminGroup?: string\n\n @IsOptional()\n @IsString()\n upnSuffix?: string\n\n @IsOptional()\n @IsString()\n netbiosName?: string\n}\n\nexport class AuthConfig {\n @IsString()\n @IsIn(['mysql', 'ldap'])\n method: 'mysql' | 'ldap' = 'mysql'\n\n @IsOptional()\n @IsString()\n encryptionKey: string\n\n @IsDefined()\n @IsNotEmptyObject()\n @IsObject()\n @ValidateNested()\n @Type(() => AuthMfaConfig)\n mfa: AuthMfaConfig = new AuthMfaConfig()\n\n @IsString()\n @IsIn(['lax', 'strict'])\n cookieSameSite: 'lax' | 'strict' = 'strict'\n\n @IsDefined()\n @IsNotEmptyObject()\n @IsObject()\n @ValidateNested()\n @Type(() => AuthTokenConfig)\n token: AuthTokenConfig\n\n @ValidateIf((o: AuthConfig) => o.method === 'ldap')\n @IsDefined()\n @IsObject()\n @ValidateNested()\n @Type(() => AuthMethodLdapConfig)\n ldap: AuthMethodLdapConfig\n}\n"],"names":["AuthConfig","AuthMethodLdapAttributesConfig","AuthMethodLdapConfig","AuthMfaConfig","AuthMfaTotpConfig","AuthTokenAccessConfig","AuthTokenConfig","AuthTokenCsrfConfig","AuthTokenRefreshConfig","AuthTokenWSConfig","enabled","issuer","SERVER_NAME","totp","name","ACCESS_KEY","expiration","toClassOnly","REFRESH_KEY","CSRF_KEY","WS_KEY","login","LDAP_LOGIN_ATTR","UID","email","LDAP_COMMON_ATTR","MAIL","value","attributes","Array","isArray","filter","v","Boolean","each","method","mfa","cookieSameSite","o"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QA6JYA;eAAAA;;QAhDAC;eAAAA;;QAaAC;eAAAA;;QA5FAC;eAAAA;;QARAC;eAAAA;;QAiBAC;eAAAA;;QAwCAC;eAAAA;;QAZAC;eAAAA;;QAdAC;eAAAA;;QAoBAC;eAAAA;;;kCAvE4B;gCAelC;wBACqB;sBAC8B;0BACR;;;;;;;;;;AAE3C,IAAA,AAAML,oBAAN,MAAMA;;aAEXM,UAAU;aAGVC,SAASC,mBAAW;;AACtB;;;;;;;AAEO,IAAA,AAAMT,gBAAN,MAAMA;;aAMXU,OAA0B,IAAIT;;AAChC;;;;;;oCAFcA;;;AAIP,IAAA,AAAMC,wBAAN,MAAMA;;aAEX,qBAAqB;QACrBS,OAAOC,gBAAU;aAQjBC,aAAa;;AACf;;;QAXaC,aAAa;;;;;;;;;;;;AAanB,IAAA,AAAMT,yBAAN,MAAMA;;aAEX,qBAAqB;QACrBM,OAAOI,iBAAW;aAQlBF,aAAa;;AACf;;;QAXaC,aAAa;;;;;;;;;;;;AAanB,IAAA,AAAMV,sBAAN,MAAMA,4BAA4BC;;QAAlC,qBAGIM,OAAeK,cAAQ;;AAClC;;;;;;AAEO,IAAA,AAAMV,oBAAN,MAAMA,0BAA0BD;;QAAhC,qBAGIM,OAAeM,YAAM;;AAChC;;;;;;AAEO,IAAA,AAAMd,kBAAN,MAAMA;AA4Bb;;;;;;oCAvBcD;;;;;;;;oCAOAG;;;;;;;;oCAOAD;;;;;;;;oCAOAE;;;AAIP,IAAA,AAAMR,iCAAN,MAAMA;;aAKXoB,QAAyBC,yBAAe,CAACC,GAAG;aAK5CC,QAAgBC,0BAAgB,CAACC,IAAI;;AACvC;;;;sCARc,EAAEC,KAAK,EAAE,GAAKA,SAASL,yBAAe,CAACC,GAAG;;;;;;;sCAM1C,EAAEI,KAAK,EAAE,GAAKA,SAASF,0BAAgB,CAACC,IAAI;;;AAInD,IAAA,AAAMxB,uBAAN,MAAMA;;aAoBX0B,aAA6C,IAAI3B;;AAanD;;sCAhCc,EAAE0B,KAAK,EAAE,GAAME,MAAMC,OAAO,CAACH,SAASA,MAAMI,MAAM,CAAC,CAACC,IAAcC,QAAQD,MAAML;;;;QAGhFO,MAAM;;;;;;;;;;;;;;;;;;;oCAeNjC;;;;;;;;;;;;;;;;;;AAgBP,IAAA,AAAMD,aAAN,MAAMA;;aAGXmC,SAA2B;aAW3BC,MAAqB,IAAIjC;aAIzBkC,iBAAmC;;AAerC;;;;QA/BS;QAAS;;;;;;;;;;;;;;oCAWJlC;;;;;;QAIL;QAAO;;;;;;;;;oCAOFG;;;;qCAGCgC,IAAkBA,EAAEH,MAAM,KAAK;;;;oCAIhCjC"}
|
|
@@ -17,8 +17,8 @@ const _passport = require("@nestjs/passport");
|
|
|
17
17
|
const _classtransformer = require("class-transformer");
|
|
18
18
|
const _nestjspino = require("nestjs-pino");
|
|
19
19
|
const _passporthttp = require("passport-http");
|
|
20
|
-
const _appconstants = require("../../app.constants");
|
|
21
20
|
const _usermodel = require("../../applications/users/models/user.model");
|
|
21
|
+
const _shared = require("../../common/shared");
|
|
22
22
|
const _cacheservice = require("../../infrastructure/cache/services/cache.service");
|
|
23
23
|
const _scope = require("../constants/scope");
|
|
24
24
|
const _authmethod = require("../models/auth-method");
|
|
@@ -64,7 +64,7 @@ let AuthBasicStrategy = class AuthBasicStrategy extends (0, _passport.PassportSt
|
|
|
64
64
|
constructor(authMethod, cache, logger){
|
|
65
65
|
super({
|
|
66
66
|
passReqToCallback: true,
|
|
67
|
-
realm:
|
|
67
|
+
realm: _shared.SERVER_NAME
|
|
68
68
|
}), this.authMethod = authMethod, this.cache = cache, this.logger = logger, this.CACHE_TTL = 900, this.CACHE_KEY_PREFIX = 'auth-webdav';
|
|
69
69
|
}
|
|
70
70
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../backend/src/authentication/guards/auth-basic.strategy.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 { Injectable } from '@nestjs/common'\nimport { AbstractStrategy, PassportStrategy } from '@nestjs/passport'\nimport { instanceToPlain, plainToInstance } from 'class-transformer'\nimport { FastifyRequest } from 'fastify'\nimport { PinoLogger } from 'nestjs-pino'\nimport { BasicStrategy } from 'passport-http'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../backend/src/authentication/guards/auth-basic.strategy.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 { Injectable } from '@nestjs/common'\nimport { AbstractStrategy, PassportStrategy } from '@nestjs/passport'\nimport { instanceToPlain, plainToInstance } from 'class-transformer'\nimport { FastifyRequest } from 'fastify'\nimport { PinoLogger } from 'nestjs-pino'\nimport { BasicStrategy } from 'passport-http'\nimport { UserModel } from '../../applications/users/models/user.model'\nimport { SERVER_NAME } from '../../common/shared'\nimport { Cache } from '../../infrastructure/cache/services/cache.service'\nimport { AUTH_SCOPE } from '../constants/scope'\nimport { AuthMethod } from '../models/auth-method'\n\n@Injectable()\nexport class AuthBasicStrategy extends PassportStrategy(BasicStrategy, 'basic') implements AbstractStrategy {\n private readonly CACHE_TTL = 900\n private readonly CACHE_KEY_PREFIX = 'auth-webdav'\n\n constructor(\n private readonly authMethod: AuthMethod,\n private readonly cache: Cache,\n private readonly logger: PinoLogger\n ) {\n super({ passReqToCallback: true, realm: SERVER_NAME })\n }\n\n async validate(req: FastifyRequest, loginOrEmail: string, password: string): Promise<Omit<UserModel, 'password'> | null> {\n loginOrEmail = loginOrEmail.trim()\n password = password.trim()\n this.logger.assign({ user: loginOrEmail })\n const authBasicUser = `${this.CACHE_KEY_PREFIX}-${req.headers['authorization'].split(' ').at(-1).toLowerCase()}`\n const userFromCache: any = await this.cache.get(authBasicUser)\n if (userFromCache === null) {\n // not authorized\n return null\n }\n if (userFromCache !== undefined) {\n // cached\n // warning: plainToInstance do not use constructor to instantiate class\n return plainToInstance(UserModel, userFromCache)\n }\n const userFromDB: UserModel = await this.authMethod.validateUser(loginOrEmail, password, req.ip, AUTH_SCOPE.WEBDAV)\n if (userFromDB !== null) {\n userFromDB.removePassword()\n }\n const userToCache: Record<string, any> | null = userFromDB ? instanceToPlain(userFromDB, { excludePrefixes: ['_'] }) : null\n this.cache.set(authBasicUser, userToCache, this.CACHE_TTL).catch((e: Error) => this.logger.error(`${this.validate.name} - ${e}`))\n return userFromDB\n }\n}\n"],"names":["AuthBasicStrategy","PassportStrategy","BasicStrategy","validate","req","loginOrEmail","password","trim","logger","assign","user","authBasicUser","CACHE_KEY_PREFIX","headers","split","at","toLowerCase","userFromCache","cache","get","undefined","plainToInstance","UserModel","userFromDB","authMethod","validateUser","ip","AUTH_SCOPE","WEBDAV","removePassword","userToCache","instanceToPlain","excludePrefixes","set","CACHE_TTL","catch","e","error","name","passReqToCallback","realm","SERVER_NAME"],"mappings":"AAAA;;;;CAIC;;;;+BAeYA;;;eAAAA;;;wBAbc;0BACwB;kCACF;4BAEtB;8BACG;2BACJ;wBACE;8BACN;uBACK;4BACA;;;;;;;;;;AAGpB,IAAA,AAAMA,oBAAN,MAAMA,0BAA0BC,IAAAA,0BAAgB,EAACC,2BAAa,EAAE;IAYrE,MAAMC,SAASC,GAAmB,EAAEC,YAAoB,EAAEC,QAAgB,EAA+C;QACvHD,eAAeA,aAAaE,IAAI;QAChCD,WAAWA,SAASC,IAAI;QACxB,IAAI,CAACC,MAAM,CAACC,MAAM,CAAC;YAAEC,MAAML;QAAa;QACxC,MAAMM,gBAAgB,GAAG,IAAI,CAACC,gBAAgB,CAAC,CAAC,EAAER,IAAIS,OAAO,CAAC,gBAAgB,CAACC,KAAK,CAAC,KAAKC,EAAE,CAAC,CAAC,GAAGC,WAAW,IAAI;QAChH,MAAMC,gBAAqB,MAAM,IAAI,CAACC,KAAK,CAACC,GAAG,CAACR;QAChD,IAAIM,kBAAkB,MAAM;YAC1B,iBAAiB;YACjB,OAAO;QACT;QACA,IAAIA,kBAAkBG,WAAW;YAC/B,SAAS;YACT,uEAAuE;YACvE,OAAOC,IAAAA,iCAAe,EAACC,oBAAS,EAAEL;QACpC;QACA,MAAMM,aAAwB,MAAM,IAAI,CAACC,UAAU,CAACC,YAAY,CAACpB,cAAcC,UAAUF,IAAIsB,EAAE,EAAEC,iBAAU,CAACC,MAAM;QAClH,IAAIL,eAAe,MAAM;YACvBA,WAAWM,cAAc;QAC3B;QACA,MAAMC,cAA0CP,aAAaQ,IAAAA,iCAAe,EAACR,YAAY;YAAES,iBAAiB;gBAAC;aAAI;QAAC,KAAK;QACvH,IAAI,CAACd,KAAK,CAACe,GAAG,CAACtB,eAAemB,aAAa,IAAI,CAACI,SAAS,EAAEC,KAAK,CAAC,CAACC,IAAa,IAAI,CAAC5B,MAAM,CAAC6B,KAAK,CAAC,GAAG,IAAI,CAAClC,QAAQ,CAACmC,IAAI,CAAC,GAAG,EAAEF,GAAG;QAC/H,OAAOb;IACT;IA9BA,YACE,AAAiBC,UAAsB,EACvC,AAAiBN,KAAY,EAC7B,AAAiBV,MAAkB,CACnC;QACA,KAAK,CAAC;YAAE+B,mBAAmB;YAAMC,OAAOC,mBAAW;QAAC,SAJnCjB,aAAAA,iBACAN,QAAAA,YACAV,SAAAA,aANF0B,YAAY,UACZtB,mBAAmB;IAQpC;AAyBF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
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";
|
|
6
|
+
Object.defineProperty(exports, "__esModule", {
|
|
7
|
+
value: true
|
|
8
|
+
});
|
|
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 LANG_DEFAULT () {
|
|
17
|
+
return LANG_DEFAULT;
|
|
18
|
+
},
|
|
19
|
+
get LANG_SUPPORTED () {
|
|
20
|
+
return LANG_SUPPORTED;
|
|
21
|
+
},
|
|
22
|
+
get normalizeLanguage () {
|
|
23
|
+
return normalizeLanguage;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
const LANG_DEFAULT = 'en';
|
|
27
|
+
const LANG_SUPPORTED = new Set([
|
|
28
|
+
'de',
|
|
29
|
+
'en',
|
|
30
|
+
'es',
|
|
31
|
+
'fr',
|
|
32
|
+
'hi',
|
|
33
|
+
'it',
|
|
34
|
+
'ja',
|
|
35
|
+
'ko',
|
|
36
|
+
'pl',
|
|
37
|
+
'pt',
|
|
38
|
+
'pt-BR',
|
|
39
|
+
'ru',
|
|
40
|
+
'tr',
|
|
41
|
+
'zh'
|
|
42
|
+
]);
|
|
43
|
+
function normalizeLanguage(language) {
|
|
44
|
+
if (!language) return null;
|
|
45
|
+
if (LANG_SUPPORTED.has(language)) {
|
|
46
|
+
return language;
|
|
47
|
+
}
|
|
48
|
+
const code = language.split('-')[0];
|
|
49
|
+
return LANG_SUPPORTED.has(code) ? code : null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=i18n.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../backend/src/common/i18n.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\nexport const LANG_DEFAULT = 'en' as const\nexport type i18nLocaleSupported = 'de' | 'en' | 'es' | 'fr' | 'hi' | 'it' | 'ja' | 'ko' | 'pl' | 'pt' | 'pt-BR' | 'ru' | 'tr' | 'zh'\nexport const LANG_SUPPORTED = new Set<i18nLocaleSupported>(['de', 'en', 'es', 'fr', 'hi', 'it', 'ja', 'ko', 'pl', 'pt', 'pt-BR', 'ru', 'tr', 'zh'])\nexport type i18nLocale = Exclude<i18nLocaleSupported, typeof LANG_DEFAULT>\n\nexport function normalizeLanguage(language: string): i18nLocaleSupported | null {\n if (!language) return null\n if (LANG_SUPPORTED.has(language as i18nLocaleSupported)) {\n return language as i18nLocaleSupported\n }\n const code = language.split('-')[0]\n return LANG_SUPPORTED.has(code as i18nLocaleSupported) ? (code as i18nLocaleSupported) : null\n}\n"],"names":["LANG_DEFAULT","LANG_SUPPORTED","normalizeLanguage","Set","language","has","code","split"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAEYA;eAAAA;;QAEAC;eAAAA;;QAGGC;eAAAA;;;AALT,MAAMF,eAAe;AAErB,MAAMC,iBAAiB,IAAIE,IAAyB;IAAC;IAAM;IAAM;IAAM;IAAM;IAAM;IAAM;IAAM;IAAM;IAAM;IAAM;IAAS;IAAM;IAAM;CAAK;AAG3I,SAASD,kBAAkBE,QAAgB;IAChD,IAAI,CAACA,UAAU,OAAO;IACtB,IAAIH,eAAeI,GAAG,CAACD,WAAkC;QACvD,OAAOA;IACT;IACA,MAAME,OAAOF,SAASG,KAAK,CAAC,IAAI,CAAC,EAAE;IACnC,OAAON,eAAeI,GAAG,CAACC,QAAgCA,OAA+B;AAC3F"}
|