@sync-in/server 1.5.2 → 1.6.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 +28 -0
- package/README.md +2 -1
- package/environment/environment.dist.min.yaml +1 -0
- package/environment/environment.dist.yaml +88 -30
- package/migrations/0002_sleepy_korath.sql +1 -0
- package/migrations/meta/0002_snapshot.json +2424 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +14 -12
- package/server/app.bootstrap.js +1 -1
- package/server/app.bootstrap.js.map +1 -1
- package/server/applications/files/services/files-manager.service.js +1 -2
- package/server/applications/files/services/files-manager.service.js.map +1 -1
- package/server/applications/files/services/files-only-office-manager.service.js +5 -6
- package/server/applications/files/services/files-only-office-manager.service.js.map +1 -1
- package/server/applications/files/utils/files.js +6 -4
- package/server/applications/files/utils/files.js.map +1 -1
- package/server/applications/links/links.controller.js +2 -2
- package/server/applications/links/links.controller.js.map +1 -1
- package/server/applications/links/services/links-manager.service.js +2 -1
- package/server/applications/links/services/links-manager.service.js.map +1 -1
- package/server/applications/links/services/links-manager.service.spec.js +6 -3
- package/server/applications/links/services/links-manager.service.spec.js.map +1 -1
- package/server/applications/notifications/constants/notifications.js +9 -0
- package/server/applications/notifications/constants/notifications.js.map +1 -1
- package/server/applications/notifications/i18n/fr.js +10 -1
- package/server/applications/notifications/i18n/fr.js.map +1 -1
- package/server/applications/notifications/interfaces/notification-properties.interface.js.map +1 -1
- package/server/applications/notifications/mails/models.js +41 -3
- package/server/applications/notifications/mails/models.js.map +1 -1
- package/server/applications/notifications/mails/templates.js +1 -1
- package/server/applications/notifications/mails/templates.js.map +1 -1
- package/server/applications/notifications/schemas/notifications.schema.js +2 -1
- package/server/applications/notifications/schemas/notifications.schema.js.map +1 -1
- package/server/applications/notifications/services/notifications-manager.service.js +16 -13
- package/server/applications/notifications/services/notifications-manager.service.js.map +1 -1
- package/server/applications/notifications/services/notifications-manager.service.spec.js +9 -8
- package/server/applications/notifications/services/notifications-manager.service.spec.js.map +1 -1
- package/server/applications/notifications/services/notifications-queries.service.js +1 -1
- package/server/applications/notifications/services/notifications-queries.service.js.map +1 -1
- package/server/applications/shares/services/shares-manager.service.js +3 -2
- package/server/applications/shares/services/shares-manager.service.js.map +1 -1
- package/server/applications/sync/constants/auth.js +2 -2
- package/server/applications/sync/constants/auth.js.map +1 -1
- package/server/applications/sync/dtos/sync-client-registration.dto.js +5 -0
- package/server/applications/sync/dtos/sync-client-registration.dto.js.map +1 -1
- package/server/applications/sync/dtos/sync-operations.dto.js +1 -2
- package/server/applications/sync/dtos/sync-operations.dto.js.map +1 -1
- package/server/applications/sync/schemas/sync-clients.schema.js +2 -1
- package/server/applications/sync/schemas/sync-clients.schema.js.map +1 -1
- package/server/applications/sync/schemas/sync-paths.schema.js +2 -1
- package/server/applications/sync/schemas/sync-paths.schema.js.map +1 -1
- package/server/applications/sync/services/sync-clients-manager.service.js +28 -20
- package/server/applications/sync/services/sync-clients-manager.service.js.map +1 -1
- package/server/applications/sync/services/sync-clients-manager.service.spec.js +24 -18
- package/server/applications/sync/services/sync-clients-manager.service.spec.js.map +1 -1
- package/server/applications/sync/services/sync-queries.service.js +5 -5
- package/server/applications/sync/services/sync-queries.service.js.map +1 -1
- package/server/applications/users/admin-users.controller.js +48 -37
- package/server/applications/users/admin-users.controller.js.map +1 -1
- package/server/applications/users/admin-users.controller.spec.js +15 -0
- package/server/applications/users/admin-users.controller.spec.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 +8 -0
- package/server/applications/users/constants/user.js.map +1 -1
- package/server/applications/users/dto/delete-user.dto.js +5 -23
- package/server/applications/users/dto/delete-user.dto.js.map +1 -1
- package/server/applications/users/dto/user-properties.dto.js +38 -3
- package/server/applications/users/dto/user-properties.dto.js.map +1 -1
- package/server/applications/users/interfaces/admin-user.interface.js.map +1 -1
- package/server/applications/users/interfaces/user-secrets.interface.js +10 -0
- package/server/applications/users/interfaces/user-secrets.interface.js.map +1 -0
- package/server/applications/users/models/user.model.js +84 -50
- 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 +2 -0
- package/server/applications/users/schemas/users.schema.js.map +1 -1
- package/server/applications/users/services/admin-users-manager.service.js +7 -19
- package/server/applications/users/services/admin-users-manager.service.js.map +1 -1
- package/server/applications/users/services/admin-users-manager.service.spec.js +7 -26
- package/server/applications/users/services/admin-users-manager.service.spec.js.map +1 -1
- package/server/applications/users/services/admin-users-queries.service.js +1 -0
- package/server/applications/users/services/admin-users-queries.service.js.map +1 -1
- package/server/applications/users/services/users-manager.service.js +138 -28
- package/server/applications/users/services/users-manager.service.js.map +1 -1
- package/server/applications/users/services/users-manager.service.spec.js +11 -9
- package/server/applications/users/services/users-manager.service.spec.js.map +1 -1
- package/server/applications/users/services/users-queries.service.js +63 -57
- package/server/applications/users/services/users-queries.service.js.map +1 -1
- package/server/applications/users/users.controller.js +48 -1
- package/server/applications/users/users.controller.js.map +1 -1
- package/server/applications/users/users.controller.spec.js +8 -1
- package/server/applications/users/users.controller.spec.js.map +1 -1
- package/server/applications/users/users.e2e-spec.js +2 -1
- package/server/applications/users/users.e2e-spec.js.map +1 -1
- package/server/applications/users/utils/avatar.js +48 -0
- package/server/applications/users/utils/avatar.js.map +1 -0
- package/server/authentication/auth.config.js +89 -26
- package/server/authentication/auth.config.js.map +1 -1
- package/server/authentication/auth.controller.js +117 -9
- package/server/authentication/auth.controller.js.map +1 -1
- package/server/authentication/auth.controller.spec.js +16 -1
- package/server/authentication/auth.controller.spec.js.map +1 -1
- package/server/authentication/auth.e2e-spec.js +4 -3
- package/server/authentication/auth.e2e-spec.js.map +1 -1
- package/server/authentication/auth.module.js +4 -1
- package/server/authentication/auth.module.js.map +1 -1
- package/server/authentication/constants/auth-ldap.js +44 -0
- package/server/authentication/constants/auth-ldap.js.map +1 -0
- package/server/authentication/constants/auth.js +37 -4
- package/server/authentication/constants/auth.js.map +1 -1
- package/server/authentication/constants/routes.js +21 -0
- package/server/authentication/constants/routes.js.map +1 -1
- package/server/authentication/constants/scope.js +20 -0
- package/server/authentication/constants/scope.js.map +1 -0
- package/server/authentication/dto/login-response.dto.js +27 -4
- package/server/authentication/dto/login-response.dto.js.map +1 -1
- package/server/authentication/dto/token-response.dto.js +5 -0
- package/server/authentication/dto/token-response.dto.js.map +1 -1
- package/server/{applications/users/dto/user-password.dto.js → authentication/dto/two-fa-verify.dto.js} +27 -9
- package/server/authentication/dto/two-fa-verify.dto.js.map +1 -0
- package/server/authentication/guards/auth-basic.strategy.js +6 -5
- package/server/authentication/guards/auth-basic.strategy.js.map +1 -1
- package/server/authentication/guards/auth-token-access.strategy.js +3 -2
- package/server/authentication/guards/auth-token-access.strategy.js.map +1 -1
- package/server/authentication/guards/auth-token-refresh.strategy.js +3 -2
- package/server/authentication/guards/auth-token-refresh.strategy.js.map +1 -1
- package/server/authentication/guards/auth-two-fa-guard.js +81 -0
- package/server/authentication/guards/auth-two-fa-guard.js.map +1 -0
- package/server/authentication/interfaces/jwt-payload.interface.js +5 -0
- package/server/authentication/interfaces/jwt-payload.interface.js.map +1 -1
- package/server/authentication/interfaces/token.interface.js +2 -0
- package/server/authentication/interfaces/token.interface.js.map +1 -1
- package/server/authentication/interfaces/two-fa-setup.interface.js +10 -0
- package/server/authentication/interfaces/two-fa-setup.interface.js.map +1 -0
- package/server/authentication/models/auth-method.js.map +1 -1
- package/server/authentication/services/auth-manager.service.js +72 -49
- package/server/authentication/services/auth-manager.service.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-database.service.js +3 -3
- package/server/authentication/services/auth-methods/auth-method-database.service.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-database.service.spec.js +5 -0
- package/server/authentication/services/auth-methods/auth-method-database.service.spec.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-ldap.service.js +151 -66
- package/server/authentication/services/auth-methods/auth-method-ldap.service.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-ldap.service.spec.js +52 -50
- package/server/authentication/services/auth-methods/auth-method-ldap.service.spec.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.js +251 -0
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.js.map +1 -0
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js +41 -0
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js.map +1 -0
- package/server/authentication/utils/crypt-secret.js +68 -0
- package/server/authentication/utils/crypt-secret.js.map +1 -0
- package/server/common/functions.js +18 -2
- package/server/common/functions.js.map +1 -1
- package/server/common/qrcode.js +34 -0
- package/server/common/qrcode.js.map +1 -0
- package/server/common/shared.js +18 -0
- package/server/common/shared.js.map +1 -1
- package/server/configuration/config.environment.js +23 -6
- package/server/configuration/config.environment.js.map +1 -1
- package/server/configuration/config.interfaces.js +10 -0
- package/server/configuration/config.interfaces.js.map +1 -0
- package/server/configuration/config.loader.js.map +1 -1
- package/server/configuration/config.validation.js +13 -13
- package/server/configuration/config.validation.js.map +1 -1
- package/server/infrastructure/cache/adapters/mysql-cache.adapter.js +6 -6
- package/server/infrastructure/cache/adapters/mysql-cache.adapter.js.map +1 -1
- package/server/infrastructure/cache/schemas/mysql-cache.schema.js +2 -1
- package/server/infrastructure/cache/schemas/mysql-cache.schema.js.map +1 -1
- package/server/infrastructure/cache/services/cache.service.js.map +1 -1
- package/server/infrastructure/database/columns.js +39 -0
- package/server/infrastructure/database/columns.js.map +1 -0
- package/server/infrastructure/database/database.config.js +0 -1
- package/server/infrastructure/database/database.config.js.map +1 -1
- package/server/infrastructure/mailer/interfaces/mail.interface.js.map +1 -1
- package/server/infrastructure/mailer/mailer.config.js +12 -0
- package/server/infrastructure/mailer/mailer.config.js.map +1 -1
- package/server/infrastructure/mailer/mailer.service.js +2 -1
- package/server/infrastructure/mailer/mailer.service.js.map +1 -1
- package/static/assets/mimes/text-x-c.svg +1 -0
- package/static/assets/pdfjs/build/pdf.mjs +2522 -914
- package/static/assets/pdfjs/build/pdf.mjs.map +1 -1
- package/static/assets/pdfjs/build/pdf.sandbox.mjs +2 -2
- package/static/assets/pdfjs/build/pdf.worker.mjs +1024 -566
- package/static/assets/pdfjs/build/pdf.worker.mjs.map +1 -1
- package/static/assets/pdfjs/version +1 -1
- package/static/assets/pdfjs/web/debugger.mjs +116 -37
- package/static/assets/pdfjs/web/images/comment-popup-editButton.svg +5 -0
- package/static/assets/pdfjs/web/locale/ach/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/af/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/an/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/ar/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ast/viewer.ftl +0 -19
- package/static/assets/pdfjs/web/locale/az/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/be/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/bg/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/bn/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/bo/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/br/viewer.ftl +0 -22
- package/static/assets/pdfjs/web/locale/brx/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/bs/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ca/viewer.ftl +12 -23
- package/static/assets/pdfjs/web/locale/cak/viewer.ftl +0 -23
- package/static/assets/pdfjs/web/locale/ckb/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/cs/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/cy/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/da/viewer.ftl +3 -35
- package/static/assets/pdfjs/web/locale/de/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/dsb/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/el/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/en-CA/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/en-GB/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/en-US/viewer.ftl +25 -13
- package/static/assets/pdfjs/web/locale/eo/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/es-AR/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/es-CL/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/es-ES/viewer.ftl +5 -32
- package/static/assets/pdfjs/web/locale/es-MX/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/et/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/eu/viewer.ftl +38 -32
- package/static/assets/pdfjs/web/locale/fa/viewer.ftl +0 -19
- package/static/assets/pdfjs/web/locale/ff/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/fi/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/fr/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/fur/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/fy-NL/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ga-IE/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/gd/viewer.ftl +0 -23
- package/static/assets/pdfjs/web/locale/gl/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/gn/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/gu-IN/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/he/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/hi-IN/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/hr/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/hsb/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/hu/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/hy-AM/viewer.ftl +372 -16
- package/static/assets/pdfjs/web/locale/hye/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/ia/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/id/viewer.ftl +38 -32
- package/static/assets/pdfjs/web/locale/is/viewer.ftl +27 -32
- package/static/assets/pdfjs/web/locale/it/viewer.ftl +0 -33
- package/static/assets/pdfjs/web/locale/ja/viewer.ftl +31 -33
- package/static/assets/pdfjs/web/locale/ka/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/kab/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/kk/viewer.ftl +31 -32
- package/static/assets/pdfjs/web/locale/km/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/kn/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/ko/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/lij/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/lo/viewer.ftl +0 -23
- package/static/assets/pdfjs/web/locale/lt/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/ltg/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/lv/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/meh/viewer.ftl +0 -14
- package/static/assets/pdfjs/web/locale/mk/viewer.ftl +0 -19
- package/static/assets/pdfjs/web/locale/ml/viewer.ftl +0 -31
- package/static/assets/pdfjs/web/locale/mr/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/ms/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/my/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/nb-NO/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ne-NP/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/nl/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/nn-NO/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/oc/viewer.ftl +0 -24
- package/static/assets/pdfjs/web/locale/pa-IN/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/pl/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/pt-BR/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/pt-PT/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/rm/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ro/viewer.ftl +5 -37
- package/static/assets/pdfjs/web/locale/ru/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/sat/viewer.ftl +0 -23
- package/static/assets/pdfjs/web/locale/sc/viewer.ftl +8 -27
- package/static/assets/pdfjs/web/locale/sco/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/si/viewer.ftl +0 -22
- package/static/assets/pdfjs/web/locale/sk/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/skr/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/sl/viewer.ftl +30 -32
- package/static/assets/pdfjs/web/locale/son/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/sq/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/sr/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/sv-SE/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/szl/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/ta/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/te/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/tg/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/th/viewer.ftl +38 -32
- package/static/assets/pdfjs/web/locale/tl/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/tr/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/trs/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/uk/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ur/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/uz/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/vi/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/xh/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/zh-CN/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/zh-TW/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/viewer.css +586 -437
- package/static/assets/pdfjs/web/viewer.html +12 -23
- package/static/assets/pdfjs/web/viewer.mjs +955 -514
- package/static/assets/pdfjs/web/viewer.mjs.map +1 -1
- package/static/assets/pdfjs/web/wasm/openjpeg.wasm +0 -0
- package/static/assets/pdfjs/web/wasm/openjpeg_nowasm_fallback.js +10 -22
- package/static/{chunk-SPTF6FSM.js → chunk-27YQB3TE.js} +1 -1
- package/static/chunk-2I4CUFUA.js +1 -0
- package/static/chunk-2MTM6SWN.js +4 -0
- package/static/{chunk-7VRUZRJG.js → chunk-34MKICK5.js} +2 -2
- package/static/chunk-5O3DIUU3.js +1 -0
- package/static/{chunk-VJRTMDEJ.js → chunk-6NMVZIIT.js} +1 -1
- package/static/{chunk-L6MU6S2V.js → chunk-7DN7ZAPU.js} +1 -1
- package/static/{chunk-MVO4WZLK.js → chunk-7FUM3JGM.js} +1 -1
- package/static/{chunk-RSS6GYNE.js → chunk-7ITZXYYJ.js} +1 -1
- package/static/chunk-7P27WBGC.js +4 -0
- package/static/chunk-ATP3BFHV.js +562 -0
- package/static/chunk-AWQ2YTVC.js +1 -0
- package/static/chunk-DSOE3FEP.js +1 -0
- package/static/{chunk-2R6HHGUR.js → chunk-EFKMBLRE.js} +1 -1
- package/static/chunk-FUFKVHPU.js +1 -0
- package/static/{chunk-MRSWNAVB.js → chunk-HCDLWTMW.js} +1 -1
- package/static/chunk-IPAC4VAF.js +1 -0
- package/static/{chunk-ZC5NIT55.js → chunk-IQOALFYU.js} +1 -1
- package/static/chunk-JASU3CIH.js +1 -0
- package/static/{chunk-6OJZWYRZ.js → chunk-JQ5FTO2M.js} +1 -1
- package/static/chunk-JUNZFADM.js +1 -0
- package/static/{chunk-LLWSLOSX.js → chunk-LJUKI4SQ.js} +1 -1
- package/static/{chunk-WI7FOANP.js → chunk-LUWQFIWR.js} +1 -1
- package/static/{chunk-BIUNUYZ5.js → chunk-ORMRCEGT.js} +1 -1
- package/static/{chunk-IZL7JPTS.js → chunk-Q7D6RN4N.js} +1 -1
- package/static/{chunk-JYXLQRHG.js → chunk-QJX6ITLW.js} +1 -1
- package/static/{chunk-YJMN3B4N.js → chunk-QQ6UQQBR.js} +1 -1
- package/static/chunk-S2HDY3OL.js +1 -0
- package/static/{chunk-NE4NDO45.js → chunk-S75P2FFI.js} +1 -1
- package/static/{chunk-CRQNEHTX.js → chunk-T3EYFSVZ.js} +1 -1
- package/static/{chunk-MCLQFZ3S.js → chunk-U34OZUZ7.js} +1 -1
- package/static/chunk-Y7EH7G5K.js +1 -0
- package/static/{chunk-MGGT6MIJ.js → chunk-ZQQPUYLU.js} +1 -1
- package/static/index.html +2 -2
- package/static/main-7SQDDVMD.js +9 -0
- package/static/{styles-FYUSO6OJ.css → styles-A5VYX3CE.css} +1 -1
- package/server/applications/users/dto/user-password.dto.js.map +0 -1
- package/static/chunk-4U5A2DEP.js +0 -4
- package/static/chunk-54EAZ2UD.js +0 -1
- package/static/chunk-7ZRXJONB.js +0 -1
- package/static/chunk-F2J2IIJE.js +0 -1
- package/static/chunk-FNFGUIQH.js +0 -4
- package/static/chunk-GGLK52CG.js +0 -1
- package/static/chunk-HW2H3ISM.js +0 -559
- package/static/chunk-HX6BBYVD.js +0 -1
- package/static/chunk-JF7S3UYQ.js +0 -1
- package/static/chunk-KSHPKI4G.js +0 -1
- package/static/chunk-VPJ2V27B.js +0 -1
- package/static/chunk-VUI3KV7V.js +0 -1
- package/static/chunk-ZXS4V7J2.js +0 -1
- package/static/main-FFIWFD2F.js +0 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../backend/src/authentication/guards/auth-token-access.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 { FastifyRequest } from 'fastify'\nimport { PinoLogger } from 'nestjs-pino'\nimport { ExtractJwt, Strategy } from 'passport-jwt'\nimport { UserModel } from '../../applications/users/models/user.model'\nimport { JwtPayload } from '../interfaces/jwt-payload.interface'\nimport { TOKEN_TYPE } from '../interfaces/token.interface'\nimport { AuthManager } from '../services/auth-manager.service'\n\n@Injectable()\nexport class AuthTokenAccessStrategy extends PassportStrategy(Strategy, 'tokenAccess') implements AbstractStrategy {\n private static accessCookieName: string\n\n constructor(\n private readonly authManager: AuthManager,\n private readonly logger: PinoLogger\n ) {\n super({\n jwtFromRequest: ExtractJwt.fromExtractors([AuthTokenAccessStrategy.extractJWTFromCookie, ExtractJwt.fromAuthHeaderAsBearerToken()]),\n secretOrKey:
|
|
1
|
+
{"version":3,"sources":["../../../../backend/src/authentication/guards/auth-token-access.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 { FastifyRequest } from 'fastify'\nimport { PinoLogger } from 'nestjs-pino'\nimport { ExtractJwt, Strategy } from 'passport-jwt'\nimport { UserModel } from '../../applications/users/models/user.model'\nimport { configuration } from '../../configuration/config.environment'\nimport { JwtPayload } from '../interfaces/jwt-payload.interface'\nimport { TOKEN_TYPE } from '../interfaces/token.interface'\nimport { AuthManager } from '../services/auth-manager.service'\n\n@Injectable()\nexport class AuthTokenAccessStrategy extends PassportStrategy(Strategy, 'tokenAccess') implements AbstractStrategy {\n private static accessCookieName: string\n\n constructor(\n private readonly authManager: AuthManager,\n private readonly logger: PinoLogger\n ) {\n super({\n jwtFromRequest: ExtractJwt.fromExtractors([AuthTokenAccessStrategy.extractJWTFromCookie, ExtractJwt.fromAuthHeaderAsBearerToken()]),\n secretOrKey: configuration.auth.token.access.secret,\n ignoreExpiration: false,\n passReqToCallback: true\n })\n AuthTokenAccessStrategy.accessCookieName = configuration.auth.token.access.name\n }\n\n validate(req: FastifyRequest, jwtPayload: JwtPayload): UserModel {\n this.logger.assign({ user: jwtPayload.identity.login })\n this.authManager.csrfValidation(req, jwtPayload, TOKEN_TYPE.ACCESS)\n return new UserModel(jwtPayload.identity)\n }\n\n static extractJWTFromCookie(req: FastifyRequest): string | null {\n if (typeof req.cookies === 'object' && req.cookies[AuthTokenAccessStrategy.accessCookieName] !== undefined) {\n return req.cookies[AuthTokenAccessStrategy.accessCookieName]\n }\n return null\n }\n}\n"],"names":["AuthTokenAccessStrategy","PassportStrategy","Strategy","validate","req","jwtPayload","logger","assign","user","identity","login","authManager","csrfValidation","TOKEN_TYPE","ACCESS","UserModel","extractJWTFromCookie","cookies","accessCookieName","undefined","jwtFromRequest","ExtractJwt","fromExtractors","fromAuthHeaderAsBearerToken","secretOrKey","configuration","auth","token","access","secret","ignoreExpiration","passReqToCallback","name"],"mappings":"AAAA;;;;CAIC;;;;+BAcYA;;;eAAAA;;;wBAZc;0BACwB;4BAExB;6BACU;2BACX;mCACI;gCAEH;oCACC;;;;;;;;;;AAGrB,IAAA,AAAMA,0BAAN,MAAMA,gCAAgCC,IAAAA,0BAAgB,EAACC,qBAAQ,EAAE;IAgBtEC,SAASC,GAAmB,EAAEC,UAAsB,EAAa;QAC/D,IAAI,CAACC,MAAM,CAACC,MAAM,CAAC;YAAEC,MAAMH,WAAWI,QAAQ,CAACC,KAAK;QAAC;QACrD,IAAI,CAACC,WAAW,CAACC,cAAc,CAACR,KAAKC,YAAYQ,0BAAU,CAACC,MAAM;QAClE,OAAO,IAAIC,oBAAS,CAACV,WAAWI,QAAQ;IAC1C;IAEA,OAAOO,qBAAqBZ,GAAmB,EAAiB;QAC9D,IAAI,OAAOA,IAAIa,OAAO,KAAK,YAAYb,IAAIa,OAAO,CAACjB,wBAAwBkB,gBAAgB,CAAC,KAAKC,WAAW;YAC1G,OAAOf,IAAIa,OAAO,CAACjB,wBAAwBkB,gBAAgB,CAAC;QAC9D;QACA,OAAO;IACT;IAxBA,YACE,AAAiBP,WAAwB,EACzC,AAAiBL,MAAkB,CACnC;QACA,KAAK,CAAC;YACJc,gBAAgBC,uBAAU,CAACC,cAAc,CAAC;gBAACtB,wBAAwBgB,oBAAoB;gBAAEK,uBAAU,CAACE,2BAA2B;aAAG;YAClIC,aAAaC,gCAAa,CAACC,IAAI,CAACC,KAAK,CAACC,MAAM,CAACC,MAAM;YACnDC,kBAAkB;YAClBC,mBAAmB;QACrB,SARiBpB,cAAAA,kBACAL,SAAAA;QAQjBN,wBAAwBkB,gBAAgB,GAAGO,gCAAa,CAACC,IAAI,CAACC,KAAK,CAACC,MAAM,CAACI,IAAI;IACjF;AAcF"}
|
|
@@ -17,6 +17,7 @@ const _passport = require("@nestjs/passport");
|
|
|
17
17
|
const _nestjspino = require("nestjs-pino");
|
|
18
18
|
const _passportjwt = require("passport-jwt");
|
|
19
19
|
const _usermodel = require("../../applications/users/models/user.model");
|
|
20
|
+
const _configenvironment = require("../../configuration/config.environment");
|
|
20
21
|
const _tokeninterface = require("../interfaces/token.interface");
|
|
21
22
|
const _authmanagerservice = require("../services/auth-manager.service");
|
|
22
23
|
function _ts_decorate(decorators, target, key, desc) {
|
|
@@ -52,11 +53,11 @@ let AuthTokenRefreshStrategy = class AuthTokenRefreshStrategy extends (0, _passp
|
|
|
52
53
|
AuthTokenRefreshStrategy.extractJWTFromCookie,
|
|
53
54
|
_passportjwt.ExtractJwt.fromAuthHeaderAsBearerToken()
|
|
54
55
|
]),
|
|
55
|
-
secretOrKey:
|
|
56
|
+
secretOrKey: _configenvironment.configuration.auth.token.refresh.secret,
|
|
56
57
|
ignoreExpiration: false,
|
|
57
58
|
passReqToCallback: true
|
|
58
59
|
}), this.authManager = authManager, this.logger = logger;
|
|
59
|
-
AuthTokenRefreshStrategy.refreshCookieName =
|
|
60
|
+
AuthTokenRefreshStrategy.refreshCookieName = _configenvironment.configuration.auth.token.refresh.name;
|
|
60
61
|
}
|
|
61
62
|
};
|
|
62
63
|
AuthTokenRefreshStrategy = _ts_decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../backend/src/authentication/guards/auth-token-refresh.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 { FastifyRequest } from 'fastify'\nimport { PinoLogger } from 'nestjs-pino'\nimport { ExtractJwt, Strategy } from 'passport-jwt'\nimport { UserModel } from '../../applications/users/models/user.model'\nimport { JwtPayload } from '../interfaces/jwt-payload.interface'\nimport { TOKEN_TYPE } from '../interfaces/token.interface'\nimport { AuthManager } from '../services/auth-manager.service'\n\n@Injectable()\nexport class AuthTokenRefreshStrategy extends PassportStrategy(Strategy, 'tokenRefresh') implements AbstractStrategy {\n private static refreshCookieName: string\n\n constructor(\n private readonly authManager: AuthManager,\n private readonly logger: PinoLogger\n ) {\n super({\n jwtFromRequest: ExtractJwt.fromExtractors([AuthTokenRefreshStrategy.extractJWTFromCookie, ExtractJwt.fromAuthHeaderAsBearerToken()]),\n secretOrKey:
|
|
1
|
+
{"version":3,"sources":["../../../../backend/src/authentication/guards/auth-token-refresh.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 { FastifyRequest } from 'fastify'\nimport { PinoLogger } from 'nestjs-pino'\nimport { ExtractJwt, Strategy } from 'passport-jwt'\nimport { UserModel } from '../../applications/users/models/user.model'\nimport { configuration } from '../../configuration/config.environment'\nimport { JwtPayload } from '../interfaces/jwt-payload.interface'\nimport { TOKEN_TYPE } from '../interfaces/token.interface'\nimport { AuthManager } from '../services/auth-manager.service'\n\n@Injectable()\nexport class AuthTokenRefreshStrategy extends PassportStrategy(Strategy, 'tokenRefresh') implements AbstractStrategy {\n private static refreshCookieName: string\n\n constructor(\n private readonly authManager: AuthManager,\n private readonly logger: PinoLogger\n ) {\n super({\n jwtFromRequest: ExtractJwt.fromExtractors([AuthTokenRefreshStrategy.extractJWTFromCookie, ExtractJwt.fromAuthHeaderAsBearerToken()]),\n secretOrKey: configuration.auth.token.refresh.secret,\n ignoreExpiration: false,\n passReqToCallback: true\n })\n AuthTokenRefreshStrategy.refreshCookieName = configuration.auth.token.refresh.name\n }\n\n validate(req: FastifyRequest, jwtPayload: JwtPayload): UserModel {\n this.logger.assign({ user: jwtPayload.identity.login })\n this.authManager.csrfValidation(req, jwtPayload, TOKEN_TYPE.REFRESH)\n // jwt expiration is used later to refresh cookies\n return new UserModel({ ...jwtPayload.identity, exp: jwtPayload.exp })\n }\n\n private static extractJWTFromCookie(req: FastifyRequest): string | null {\n if (typeof req.cookies === 'object' && req.cookies[AuthTokenRefreshStrategy.refreshCookieName] !== undefined) {\n return req.cookies[AuthTokenRefreshStrategy.refreshCookieName]\n }\n return null\n }\n}\n"],"names":["AuthTokenRefreshStrategy","PassportStrategy","Strategy","validate","req","jwtPayload","logger","assign","user","identity","login","authManager","csrfValidation","TOKEN_TYPE","REFRESH","UserModel","exp","extractJWTFromCookie","cookies","refreshCookieName","undefined","jwtFromRequest","ExtractJwt","fromExtractors","fromAuthHeaderAsBearerToken","secretOrKey","configuration","auth","token","refresh","secret","ignoreExpiration","passReqToCallback","name"],"mappings":"AAAA;;;;CAIC;;;;+BAcYA;;;eAAAA;;;wBAZc;0BACwB;4BAExB;6BACU;2BACX;mCACI;gCAEH;oCACC;;;;;;;;;;AAGrB,IAAA,AAAMA,2BAAN,MAAMA,iCAAiCC,IAAAA,0BAAgB,EAACC,qBAAQ,EAAE;IAgBvEC,SAASC,GAAmB,EAAEC,UAAsB,EAAa;QAC/D,IAAI,CAACC,MAAM,CAACC,MAAM,CAAC;YAAEC,MAAMH,WAAWI,QAAQ,CAACC,KAAK;QAAC;QACrD,IAAI,CAACC,WAAW,CAACC,cAAc,CAACR,KAAKC,YAAYQ,0BAAU,CAACC,OAAO;QACnE,kDAAkD;QAClD,OAAO,IAAIC,oBAAS,CAAC;YAAE,GAAGV,WAAWI,QAAQ;YAAEO,KAAKX,WAAWW,GAAG;QAAC;IACrE;IAEA,OAAeC,qBAAqBb,GAAmB,EAAiB;QACtE,IAAI,OAAOA,IAAIc,OAAO,KAAK,YAAYd,IAAIc,OAAO,CAAClB,yBAAyBmB,iBAAiB,CAAC,KAAKC,WAAW;YAC5G,OAAOhB,IAAIc,OAAO,CAAClB,yBAAyBmB,iBAAiB,CAAC;QAChE;QACA,OAAO;IACT;IAzBA,YACE,AAAiBR,WAAwB,EACzC,AAAiBL,MAAkB,CACnC;QACA,KAAK,CAAC;YACJe,gBAAgBC,uBAAU,CAACC,cAAc,CAAC;gBAACvB,yBAAyBiB,oBAAoB;gBAAEK,uBAAU,CAACE,2BAA2B;aAAG;YACnIC,aAAaC,gCAAa,CAACC,IAAI,CAACC,KAAK,CAACC,OAAO,CAACC,MAAM;YACpDC,kBAAkB;YAClBC,mBAAmB;QACrB,SARiBrB,cAAAA,kBACAL,SAAAA;QAQjBN,yBAAyBmB,iBAAiB,GAAGO,gCAAa,CAACC,IAAI,CAACC,KAAK,CAACC,OAAO,CAACI,IAAI;IACpF;AAeF"}
|
|
@@ -0,0 +1,81 @@
|
|
|
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 AuthTwoFaGuard () {
|
|
17
|
+
return AuthTwoFaGuard;
|
|
18
|
+
},
|
|
19
|
+
get AuthTwoFaGuardWithoutPassword () {
|
|
20
|
+
return AuthTwoFaGuardWithoutPassword;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
const _common = require("@nestjs/common");
|
|
24
|
+
const _configenvironment = require("../../configuration/config.environment");
|
|
25
|
+
const _auth = require("../constants/auth");
|
|
26
|
+
const _authmethodtwofaservice = require("../services/auth-methods/auth-method-two-fa.service");
|
|
27
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
28
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
29
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
30
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
31
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
32
|
+
}
|
|
33
|
+
function _ts_metadata(k, v) {
|
|
34
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
35
|
+
}
|
|
36
|
+
const AuthTwoFaGuard = AuthTwoFaGuardFactory();
|
|
37
|
+
const AuthTwoFaGuardWithoutPassword = AuthTwoFaGuardFactory({
|
|
38
|
+
withPassword: false
|
|
39
|
+
});
|
|
40
|
+
function AuthTwoFaGuardFactory(options = {
|
|
41
|
+
withPassword: true
|
|
42
|
+
}) {
|
|
43
|
+
let MixinAuthTwoFaGuard = class MixinAuthTwoFaGuard {
|
|
44
|
+
async canActivate(ctx) {
|
|
45
|
+
const req = ctx.switchToHttp().getRequest();
|
|
46
|
+
const user = await this.authMethod2FA.loadUser(req.user.id, req.ip);
|
|
47
|
+
if (options.withPassword) {
|
|
48
|
+
if (!req.headers[_auth.TWO_FA_HEADER_PASSWORD]) {
|
|
49
|
+
throw new _common.HttpException('Missing TWO-FA password', _common.HttpStatus.FORBIDDEN);
|
|
50
|
+
}
|
|
51
|
+
await this.authMethod2FA.verifyUserPassword(user, req.headers[_auth.TWO_FA_HEADER_PASSWORD], req.ip);
|
|
52
|
+
}
|
|
53
|
+
if (!_configenvironment.configuration.auth.mfa.totp.enabled || !user.twoFaEnabled) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
if (!req.headers[_auth.TWO_FA_HEADER_CODE]) {
|
|
57
|
+
throw new _common.HttpException('Missing TWO-FA code', _common.HttpStatus.FORBIDDEN);
|
|
58
|
+
}
|
|
59
|
+
const auth = await this.authMethod2FA.verify({
|
|
60
|
+
code: req.headers[_auth.TWO_FA_HEADER_CODE]
|
|
61
|
+
}, req);
|
|
62
|
+
if (!auth.success) {
|
|
63
|
+
throw new _common.HttpException(auth.message, _common.HttpStatus.FORBIDDEN);
|
|
64
|
+
}
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
constructor(authMethod2FA){
|
|
68
|
+
this.authMethod2FA = authMethod2FA;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
MixinAuthTwoFaGuard = _ts_decorate([
|
|
72
|
+
(0, _common.Injectable)(),
|
|
73
|
+
_ts_metadata("design:type", Function),
|
|
74
|
+
_ts_metadata("design:paramtypes", [
|
|
75
|
+
typeof _authmethodtwofaservice.AuthMethod2FA === "undefined" ? Object : _authmethodtwofaservice.AuthMethod2FA
|
|
76
|
+
])
|
|
77
|
+
], MixinAuthTwoFaGuard);
|
|
78
|
+
return (0, _common.mixin)(MixinAuthTwoFaGuard);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
//# sourceMappingURL=auth-two-fa-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../backend/src/authentication/guards/auth-two-fa-guard.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 { CanActivate, ExecutionContext, HttpException, HttpStatus, Injectable, mixin, Type } from '@nestjs/common'\nimport { configuration } from '../../configuration/config.environment'\nimport { TWO_FA_HEADER_CODE, TWO_FA_HEADER_PASSWORD } from '../constants/auth'\nimport { FastifyAuthenticatedRequest } from '../interfaces/auth-request.interface'\nimport { AuthMethod2FA } from '../services/auth-methods/auth-method-two-fa.service'\n\nexport const AuthTwoFaGuard = AuthTwoFaGuardFactory()\nexport const AuthTwoFaGuardWithoutPassword = AuthTwoFaGuardFactory({ withPassword: false })\n\ninterface TwoFaGuardOptions {\n withPassword?: boolean\n}\n\nfunction AuthTwoFaGuardFactory(options: TwoFaGuardOptions = { withPassword: true }): Type<CanActivate> {\n @Injectable()\n class MixinAuthTwoFaGuard implements CanActivate {\n constructor(private readonly authMethod2FA: AuthMethod2FA) {}\n\n async canActivate(ctx: ExecutionContext): Promise<boolean> {\n const req: FastifyAuthenticatedRequest = ctx.switchToHttp().getRequest()\n const user = await this.authMethod2FA.loadUser(req.user.id, req.ip)\n\n if (options.withPassword) {\n if (!req.headers[TWO_FA_HEADER_PASSWORD]) {\n throw new HttpException('Missing TWO-FA password', HttpStatus.FORBIDDEN)\n }\n await this.authMethod2FA.verifyUserPassword(user, req.headers[TWO_FA_HEADER_PASSWORD] as string, req.ip)\n }\n\n if (!configuration.auth.mfa.totp.enabled || !user.twoFaEnabled) {\n return true\n }\n\n if (!req.headers[TWO_FA_HEADER_CODE]) {\n throw new HttpException('Missing TWO-FA code', HttpStatus.FORBIDDEN)\n }\n\n const auth = await this.authMethod2FA.verify({ code: req.headers[TWO_FA_HEADER_CODE] as string }, req)\n\n if (!auth.success) {\n throw new HttpException(auth.message, HttpStatus.FORBIDDEN)\n }\n\n return true\n }\n }\n\n return mixin(MixinAuthTwoFaGuard)\n}\n"],"names":["AuthTwoFaGuard","AuthTwoFaGuardWithoutPassword","AuthTwoFaGuardFactory","withPassword","options","MixinAuthTwoFaGuard","canActivate","ctx","req","switchToHttp","getRequest","user","authMethod2FA","loadUser","id","ip","headers","TWO_FA_HEADER_PASSWORD","HttpException","HttpStatus","FORBIDDEN","verifyUserPassword","configuration","auth","mfa","totp","enabled","twoFaEnabled","TWO_FA_HEADER_CODE","verify","code","success","message","mixin"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAQYA;eAAAA;;QACAC;eAAAA;;;wBAPqF;mCACpE;sBAC6B;wCAE7B;;;;;;;;;;AAEvB,MAAMD,iBAAiBE;AACvB,MAAMD,gCAAgCC,sBAAsB;IAAEC,cAAc;AAAM;AAMzF,SAASD,sBAAsBE,UAA6B;IAAED,cAAc;AAAK,CAAC;IAChF,IAAA,AACME,sBADN,MACMA;QAGJ,MAAMC,YAAYC,GAAqB,EAAoB;YACzD,MAAMC,MAAmCD,IAAIE,YAAY,GAAGC,UAAU;YACtE,MAAMC,OAAO,MAAM,IAAI,CAACC,aAAa,CAACC,QAAQ,CAACL,IAAIG,IAAI,CAACG,EAAE,EAAEN,IAAIO,EAAE;YAElE,IAAIX,QAAQD,YAAY,EAAE;gBACxB,IAAI,CAACK,IAAIQ,OAAO,CAACC,4BAAsB,CAAC,EAAE;oBACxC,MAAM,IAAIC,qBAAa,CAAC,2BAA2BC,kBAAU,CAACC,SAAS;gBACzE;gBACA,MAAM,IAAI,CAACR,aAAa,CAACS,kBAAkB,CAACV,MAAMH,IAAIQ,OAAO,CAACC,4BAAsB,CAAC,EAAYT,IAAIO,EAAE;YACzG;YAEA,IAAI,CAACO,gCAAa,CAACC,IAAI,CAACC,GAAG,CAACC,IAAI,CAACC,OAAO,IAAI,CAACf,KAAKgB,YAAY,EAAE;gBAC9D,OAAO;YACT;YAEA,IAAI,CAACnB,IAAIQ,OAAO,CAACY,wBAAkB,CAAC,EAAE;gBACpC,MAAM,IAAIV,qBAAa,CAAC,uBAAuBC,kBAAU,CAACC,SAAS;YACrE;YAEA,MAAMG,OAAO,MAAM,IAAI,CAACX,aAAa,CAACiB,MAAM,CAAC;gBAAEC,MAAMtB,IAAIQ,OAAO,CAACY,wBAAkB,CAAC;YAAW,GAAGpB;YAElG,IAAI,CAACe,KAAKQ,OAAO,EAAE;gBACjB,MAAM,IAAIb,qBAAa,CAACK,KAAKS,OAAO,EAAEb,kBAAU,CAACC,SAAS;YAC5D;YAEA,OAAO;QACT;QA5BA,YAAY,AAAiBR,aAA4B,CAAE;iBAA9BA,gBAAAA;QAA+B;IA6B9D;;;;;;;;IAEA,OAAOqB,IAAAA,aAAK,EAAC5B;AACf"}
|
|
@@ -13,6 +13,9 @@ function _export(target, all) {
|
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
15
|
_export(exports, {
|
|
16
|
+
get JwtIdentity2FaPayload () {
|
|
17
|
+
return JwtIdentity2FaPayload;
|
|
18
|
+
},
|
|
16
19
|
get JwtIdentityPayload () {
|
|
17
20
|
return JwtIdentityPayload;
|
|
18
21
|
},
|
|
@@ -22,6 +25,8 @@ _export(exports, {
|
|
|
22
25
|
});
|
|
23
26
|
let JwtIdentityPayload = class JwtIdentityPayload {
|
|
24
27
|
};
|
|
28
|
+
let JwtIdentity2FaPayload = class JwtIdentity2FaPayload {
|
|
29
|
+
};
|
|
25
30
|
let JwtPayload = class JwtPayload {
|
|
26
31
|
};
|
|
27
32
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../backend/src/authentication/interfaces/jwt-payload.interface.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nexport class JwtIdentityPayload {\n id: number\n login: string\n email: string\n fullName: string\n role: number\n applications: string[]\n impersonatedFromId?: number\n impersonatedClientId?: string\n clientId?: string\n}\n\nexport class JwtPayload {\n identity: JwtIdentityPayload\n csrf?: string\n iat?: number\n exp: number\n}\n"],"names":["JwtIdentityPayload","JwtPayload"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;
|
|
1
|
+
{"version":3,"sources":["../../../../backend/src/authentication/interfaces/jwt-payload.interface.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nexport class JwtIdentityPayload {\n id: number\n login: string\n email: string\n fullName: string\n language: string\n role: number\n applications: string[]\n impersonatedFromId?: number\n impersonatedClientId?: string\n clientId?: string\n twoFaEnabled?: boolean\n}\n\nexport class JwtIdentity2FaPayload {\n id: number\n login: string\n language: string\n role: number\n twoFaEnabled: true\n}\n\nexport class JwtPayload {\n identity: JwtIdentityPayload\n csrf?: string\n iat?: number\n exp: number\n}\n"],"names":["JwtIdentity2FaPayload","JwtIdentityPayload","JwtPayload"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAgBYA;eAAAA;;QAdAC;eAAAA;;QAsBAC;eAAAA;;;AAtBN,IAAA,AAAMD,qBAAN,MAAMA;AAYb;AAEO,IAAA,AAAMD,wBAAN,MAAMA;AAMb;AAEO,IAAA,AAAME,aAAN,MAAMA;AAKb"}
|
|
@@ -14,9 +14,11 @@ Object.defineProperty(exports, "TOKEN_TYPE", {
|
|
|
14
14
|
});
|
|
15
15
|
var TOKEN_TYPE = /*#__PURE__*/ function(TOKEN_TYPE) {
|
|
16
16
|
TOKEN_TYPE["ACCESS"] = "access";
|
|
17
|
+
TOKEN_TYPE["ACCESS_2FA"] = "access_2fa";
|
|
17
18
|
TOKEN_TYPE["REFRESH"] = "refresh";
|
|
18
19
|
TOKEN_TYPE["WS"] = "ws";
|
|
19
20
|
TOKEN_TYPE["CSRF"] = "csrf";
|
|
21
|
+
TOKEN_TYPE["CSRF_2FA"] = "csrf_2fa";
|
|
20
22
|
return TOKEN_TYPE;
|
|
21
23
|
}({});
|
|
22
24
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../backend/src/authentication/interfaces/token.interface.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nexport enum TOKEN_TYPE {\n ACCESS = 'access',\n REFRESH = 'refresh',\n WS = 'ws',\n CSRF = 'csrf'\n}\n"],"names":["TOKEN_TYPE"],"mappings":"AAAA;;;;CAIC;;;;+BAEWA;;;eAAAA;;;AAAL,IAAA,AAAKA,oCAAAA
|
|
1
|
+
{"version":3,"sources":["../../../../backend/src/authentication/interfaces/token.interface.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nexport enum TOKEN_TYPE {\n ACCESS = 'access',\n ACCESS_2FA = 'access_2fa',\n REFRESH = 'refresh',\n WS = 'ws',\n CSRF = 'csrf',\n CSRF_2FA = 'csrf_2fa'\n}\n"],"names":["TOKEN_TYPE"],"mappings":"AAAA;;;;CAIC;;;;+BAEWA;;;eAAAA;;;AAAL,IAAA,AAAKA,oCAAAA;;;;;;;WAAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
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
|
+
|
|
10
|
+
//# sourceMappingURL=two-fa-setup.interface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../backend/src/authentication/interfaces/two-fa-setup.interface.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nexport interface TwoFaSetup {\n secret: string\n qrDataUrl: string\n}\n\nexport interface TwoFaVerifyResult {\n success: boolean\n message: string\n}\n\nexport interface TwoFaEnableResult extends TwoFaVerifyResult {\n recoveryCodes: string[]\n}\n"],"names":[],"mappings":"AAAA;;;;CAIC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../backend/src/authentication/models/auth-method.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 { UserModel } from '../../applications/users/models/user.model'\n\nexport abstract class AuthMethod {\n abstract validateUser(loginOrEmail: string, password: string, ip?: string): Promise<UserModel>\n}\n"],"names":["AuthMethod"],"mappings":"AAAA;;;;CAIC;;;;+
|
|
1
|
+
{"version":3,"sources":["../../../../backend/src/authentication/models/auth-method.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 type { UserModel } from '../../applications/users/models/user.model'\nimport type { AUTH_SCOPE } from '../constants/scope'\n\nexport abstract class AuthMethod {\n abstract validateUser(loginOrEmail: string, password: string, ip?: string, scope?: AUTH_SCOPE): Promise<UserModel>\n}\n"],"names":["AuthMethod"],"mappings":"AAAA;;;;CAIC;;;;+BAKqBA;;;eAAAA;;;AAAf,IAAA,AAAeA,aAAf,MAAeA;AAEtB"}
|
|
@@ -14,12 +14,12 @@ Object.defineProperty(exports, "AuthManager", {
|
|
|
14
14
|
});
|
|
15
15
|
const _cookie = require("@fastify/cookie");
|
|
16
16
|
const _common = require("@nestjs/common");
|
|
17
|
-
const _config = require("@nestjs/config");
|
|
18
17
|
const _jwt = require("@nestjs/jwt");
|
|
19
18
|
const _nodecrypto = /*#__PURE__*/ _interop_require_default(require("node:crypto"));
|
|
20
19
|
const _applicationsconstants = require("../../applications/applications.constants");
|
|
21
20
|
const _functions = require("../../common/functions");
|
|
22
21
|
const _shared = require("../../common/shared");
|
|
22
|
+
const _configenvironment = require("../../configuration/config.environment");
|
|
23
23
|
const _auth = require("../constants/auth");
|
|
24
24
|
const _loginresponsedto = require("../dto/login-response.dto");
|
|
25
25
|
const _tokeninterface = require("../interfaces/token.interface");
|
|
@@ -44,8 +44,8 @@ let AuthManager = class AuthManager {
|
|
|
44
44
|
this.logger.error(`${this.getTokens.name} - token refresh has incorrect expiration : *${user.login}*`);
|
|
45
45
|
throw new _common.HttpException('Token has expired', _common.HttpStatus.FORBIDDEN);
|
|
46
46
|
}
|
|
47
|
-
const accessExpiration = (0, _functions.convertHumanTimeToSeconds)(
|
|
48
|
-
const refreshExpiration = refresh ? user.exp - currentTime : (0, _functions.convertHumanTimeToSeconds)(
|
|
47
|
+
const accessExpiration = (0, _functions.convertHumanTimeToSeconds)(_configenvironment.configuration.auth.token.access.expiration);
|
|
48
|
+
const refreshExpiration = refresh ? user.exp - currentTime : (0, _functions.convertHumanTimeToSeconds)(_configenvironment.configuration.auth.token.refresh.expiration);
|
|
49
49
|
return {
|
|
50
50
|
[_tokeninterface.TOKEN_TYPE.ACCESS]: await this.jwtSign(user, _tokeninterface.TOKEN_TYPE.ACCESS, accessExpiration),
|
|
51
51
|
[_tokeninterface.TOKEN_TYPE.REFRESH]: await this.jwtSign(user, _tokeninterface.TOKEN_TYPE.REFRESH, refreshExpiration),
|
|
@@ -53,20 +53,31 @@ let AuthManager = class AuthManager {
|
|
|
53
53
|
[`${_tokeninterface.TOKEN_TYPE.REFRESH}_expiration`]: refreshExpiration + currentTime
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
|
-
async setCookies(user, res) {
|
|
57
|
-
|
|
56
|
+
async setCookies(user, res, init2FaVerify = false) {
|
|
57
|
+
// If `verify2Fa` is true, it sets the cookies and response required for valid 2FA authentication.
|
|
58
|
+
const verify2Fa = init2FaVerify && _configenvironment.configuration.auth.mfa.totp.enabled && user.twoFaEnabled;
|
|
59
|
+
const response = verify2Fa ? new _loginresponsedto.LoginVerify2FaDto(_configenvironment.serverConfig) : new _loginresponsedto.LoginResponseDto(user, _configenvironment.serverConfig);
|
|
58
60
|
const currentTime = (0, _shared.currentTimeStamp)();
|
|
59
61
|
const csrfToken = _nodecrypto.default.randomUUID();
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
const tokenTypes = verify2Fa ? _auth.TOKEN_2FA_TYPES : _auth.TOKEN_TYPES;
|
|
63
|
+
for (const type of tokenTypes){
|
|
64
|
+
const isCSRFToken = type === _tokeninterface.TOKEN_TYPE.CSRF || type === _tokeninterface.TOKEN_TYPE.CSRF_2FA;
|
|
65
|
+
const tokenExpiration = (0, _functions.convertHumanTimeToSeconds)(_configenvironment.configuration.auth.token[type].expiration);
|
|
66
|
+
let cookieValue;
|
|
67
|
+
if (isCSRFToken) {
|
|
68
|
+
cookieValue = csrfToken;
|
|
69
|
+
} else if (verify2Fa) {
|
|
70
|
+
cookieValue = await this.jwtSign2Fa(user, type, tokenExpiration, csrfToken);
|
|
71
|
+
} else {
|
|
72
|
+
cookieValue = await this.jwtSign(user, type, tokenExpiration, csrfToken);
|
|
73
|
+
}
|
|
74
|
+
res.setCookie(_configenvironment.configuration.auth.token[type].name, cookieValue, {
|
|
75
|
+
signed: isCSRFToken,
|
|
65
76
|
path: _auth.TOKEN_PATHS[type],
|
|
66
|
-
maxAge:
|
|
67
|
-
httpOnly:
|
|
77
|
+
maxAge: tokenExpiration,
|
|
78
|
+
httpOnly: !isCSRFToken
|
|
68
79
|
});
|
|
69
|
-
if (type === _tokeninterface.TOKEN_TYPE.ACCESS || type === _tokeninterface.TOKEN_TYPE.REFRESH) {
|
|
80
|
+
if (type === _tokeninterface.TOKEN_TYPE.ACCESS || type === _tokeninterface.TOKEN_TYPE.REFRESH || type === _tokeninterface.TOKEN_TYPE.ACCESS_2FA) {
|
|
70
81
|
response.token[`${type}_expiration`] = tokenExpiration + currentTime;
|
|
71
82
|
}
|
|
72
83
|
}
|
|
@@ -76,25 +87,22 @@ let AuthManager = class AuthManager {
|
|
|
76
87
|
const response = {};
|
|
77
88
|
const currentTime = (0, _shared.currentTimeStamp)();
|
|
78
89
|
let refreshTokenExpiration;
|
|
79
|
-
let refreshMaxAge;
|
|
80
90
|
// refresh cookie must have the `exp` attribute
|
|
81
91
|
// reuse token expiration to make it final
|
|
82
92
|
if (user.exp && user.exp > currentTime) {
|
|
83
93
|
refreshTokenExpiration = user.exp - currentTime;
|
|
84
|
-
refreshMaxAge = refreshTokenExpiration;
|
|
85
94
|
} else {
|
|
86
95
|
this.logger.error(`${this.refreshCookies.name} - token ${_tokeninterface.TOKEN_TYPE.REFRESH} has incorrect expiration : *${user.login}*`);
|
|
87
96
|
throw new _common.HttpException('Token has expired', _common.HttpStatus.FORBIDDEN);
|
|
88
97
|
}
|
|
89
98
|
const csrfToken = _nodecrypto.default.randomUUID();
|
|
90
99
|
for (const type of _auth.TOKEN_TYPES){
|
|
91
|
-
const tokenExpiration = type === _tokeninterface.TOKEN_TYPE.
|
|
92
|
-
const maxAge = type === _tokeninterface.TOKEN_TYPE.REFRESH ? refreshMaxAge : (0, _functions.convertHumanTimeToSeconds)(this.authConfig.token[type].cookieMaxAge);
|
|
100
|
+
const tokenExpiration = type === _tokeninterface.TOKEN_TYPE.ACCESS ? (0, _functions.convertHumanTimeToSeconds)(_configenvironment.configuration.auth.token[_tokeninterface.TOKEN_TYPE.ACCESS].expiration) : refreshTokenExpiration;
|
|
93
101
|
const cookieValue = type === _tokeninterface.TOKEN_TYPE.CSRF ? csrfToken : await this.jwtSign(user, type, tokenExpiration, csrfToken);
|
|
94
|
-
res.setCookie(
|
|
102
|
+
res.setCookie(_configenvironment.configuration.auth.token[type].name, cookieValue, {
|
|
95
103
|
signed: type === _tokeninterface.TOKEN_TYPE.CSRF,
|
|
96
104
|
path: _auth.TOKEN_PATHS[type],
|
|
97
|
-
maxAge:
|
|
105
|
+
maxAge: tokenExpiration,
|
|
98
106
|
httpOnly: type !== _tokeninterface.TOKEN_TYPE.CSRF
|
|
99
107
|
});
|
|
100
108
|
if (type === _tokeninterface.TOKEN_TYPE.ACCESS || type === _tokeninterface.TOKEN_TYPE.REFRESH) {
|
|
@@ -105,40 +113,19 @@ let AuthManager = class AuthManager {
|
|
|
105
113
|
}
|
|
106
114
|
async clearCookies(res) {
|
|
107
115
|
for (const [type, path] of Object.entries(_auth.TOKEN_PATHS)){
|
|
108
|
-
res.clearCookie(
|
|
116
|
+
res.clearCookie(_configenvironment.configuration.auth.token[type].name, {
|
|
109
117
|
path: path,
|
|
110
118
|
httpOnly: type !== _tokeninterface.TOKEN_TYPE.CSRF
|
|
111
119
|
});
|
|
112
120
|
}
|
|
113
121
|
}
|
|
114
|
-
jwtSign(user, type, expiration, csrfToken) {
|
|
115
|
-
return this.jwt.signAsync({
|
|
116
|
-
identity: {
|
|
117
|
-
id: user.id,
|
|
118
|
-
login: user.login,
|
|
119
|
-
email: user.email,
|
|
120
|
-
fullName: user.fullName,
|
|
121
|
-
role: user.role,
|
|
122
|
-
applications: user.applications,
|
|
123
|
-
impersonatedFromId: user.impersonatedFromId || undefined,
|
|
124
|
-
impersonatedClientId: user.impersonatedClientId || undefined,
|
|
125
|
-
clientId: user.clientId || undefined
|
|
126
|
-
},
|
|
127
|
-
...(type === _tokeninterface.TOKEN_TYPE.ACCESS || type === _tokeninterface.TOKEN_TYPE.REFRESH) && {
|
|
128
|
-
csrf: csrfToken
|
|
129
|
-
}
|
|
130
|
-
}, {
|
|
131
|
-
secret: this.authConfig.token[type].secret,
|
|
132
|
-
expiresIn: expiration
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
122
|
csrfValidation(req, jwtPayload, type) {
|
|
136
123
|
// ignore safe methods
|
|
137
124
|
if (_applicationsconstants.HTTP_CSRF_IGNORED_METHODS.has(req.method)) {
|
|
138
125
|
return;
|
|
139
126
|
}
|
|
140
|
-
// check csrf only for access
|
|
141
|
-
if (typeof req.cookies !== 'object' || req.cookies[
|
|
127
|
+
// check csrf only for access and refresh cookies
|
|
128
|
+
if (typeof req.cookies !== 'object' || req.cookies[_configenvironment.configuration.auth.token[type].name] === undefined) {
|
|
142
129
|
return;
|
|
143
130
|
}
|
|
144
131
|
if (!jwtPayload.csrf) {
|
|
@@ -149,25 +136,61 @@ let AuthManager = class AuthManager {
|
|
|
149
136
|
this.logger.warn(`${this.csrfValidation.name} - ${_auth.CSRF_ERROR.MISSING_HEADERS}`);
|
|
150
137
|
throw new _common.HttpException(_auth.CSRF_ERROR.MISSING_HEADERS, _common.HttpStatus.FORBIDDEN);
|
|
151
138
|
}
|
|
152
|
-
const csrfHeader = (0, _cookie.unsign)(req.headers[_auth.CSRF_KEY],
|
|
139
|
+
const csrfHeader = (0, _cookie.unsign)(req.headers[_auth.CSRF_KEY], _configenvironment.configuration.auth.token.csrf.secret);
|
|
153
140
|
if (jwtPayload.csrf !== csrfHeader.value) {
|
|
154
141
|
this.logger.warn(`${this.csrfValidation.name} - ${_auth.CSRF_ERROR.MISMATCH}`);
|
|
155
142
|
throw new _common.HttpException(_auth.CSRF_ERROR.MISMATCH, _common.HttpStatus.FORBIDDEN);
|
|
156
143
|
}
|
|
157
144
|
}
|
|
158
|
-
|
|
145
|
+
jwtSign(user, type, expiration, csrfToken) {
|
|
146
|
+
return this.jwt.signAsync({
|
|
147
|
+
identity: {
|
|
148
|
+
id: user.id,
|
|
149
|
+
login: user.login,
|
|
150
|
+
email: user.email,
|
|
151
|
+
fullName: user.fullName,
|
|
152
|
+
language: user.language,
|
|
153
|
+
role: user.role,
|
|
154
|
+
applications: user.applications,
|
|
155
|
+
impersonatedFromId: user.impersonatedFromId || undefined,
|
|
156
|
+
impersonatedClientId: user.impersonatedClientId || undefined,
|
|
157
|
+
clientId: user.clientId || undefined,
|
|
158
|
+
twoFaEnabled: user.twoFaEnabled || undefined
|
|
159
|
+
},
|
|
160
|
+
...(type === _tokeninterface.TOKEN_TYPE.ACCESS || type === _tokeninterface.TOKEN_TYPE.REFRESH) && {
|
|
161
|
+
csrf: csrfToken
|
|
162
|
+
}
|
|
163
|
+
}, {
|
|
164
|
+
secret: _configenvironment.configuration.auth.token[type].secret,
|
|
165
|
+
expiresIn: expiration
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
jwtSign2Fa(user, type, expiration, csrfToken) {
|
|
169
|
+
// Restrict the temporary token to the minimum required information
|
|
170
|
+
return this.jwt.signAsync({
|
|
171
|
+
identity: {
|
|
172
|
+
id: user.id,
|
|
173
|
+
login: user.login,
|
|
174
|
+
language: user.language,
|
|
175
|
+
role: user.role,
|
|
176
|
+
twoFaEnabled: true
|
|
177
|
+
},
|
|
178
|
+
csrf: csrfToken
|
|
179
|
+
}, {
|
|
180
|
+
secret: _configenvironment.configuration.auth.token[type].secret,
|
|
181
|
+
expiresIn: expiration
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
constructor(jwt){
|
|
159
185
|
this.jwt = jwt;
|
|
160
|
-
this.config = config;
|
|
161
186
|
this.logger = new _common.Logger(AuthManager.name);
|
|
162
|
-
this.authConfig = this.config.get('auth');
|
|
163
187
|
}
|
|
164
188
|
};
|
|
165
189
|
AuthManager = _ts_decorate([
|
|
166
190
|
(0, _common.Injectable)(),
|
|
167
191
|
_ts_metadata("design:type", Function),
|
|
168
192
|
_ts_metadata("design:paramtypes", [
|
|
169
|
-
typeof _jwt.JwtService === "undefined" ? Object : _jwt.JwtService
|
|
170
|
-
typeof _config.ConfigService === "undefined" ? Object : _config.ConfigService
|
|
193
|
+
typeof _jwt.JwtService === "undefined" ? Object : _jwt.JwtService
|
|
171
194
|
])
|
|
172
195
|
], AuthManager);
|
|
173
196
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../backend/src/authentication/services/auth-manager.service.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\nimport { unsign, UnsignResult } from '@fastify/cookie'\nimport { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport { ConfigService } from '@nestjs/config'\nimport { JwtService } from '@nestjs/jwt'\nimport { FastifyReply, FastifyRequest } from 'fastify'\nimport crypto from 'node:crypto'\nimport { HTTP_CSRF_IGNORED_METHODS } from '../../applications/applications.constants'\nimport { UserModel } from '../../applications/users/models/user.model'\nimport { convertHumanTimeToSeconds } from '../../common/functions'\nimport { currentTimeStamp } from '../../common/shared'\nimport { AuthConfig } from '../auth.config'\nimport { CSRF_ERROR, CSRF_KEY, TOKEN_PATHS, TOKEN_TYPES } from '../constants/auth'\nimport { LoginResponseDto } from '../dto/login-response.dto'\nimport { TokenResponseDto } from '../dto/token-response.dto'\nimport { JwtIdentityPayload, JwtPayload } from '../interfaces/jwt-payload.interface'\nimport { TOKEN_TYPE } from '../interfaces/token.interface'\n\n@Injectable()\nexport class AuthManager {\n private readonly logger = new Logger(AuthManager.name)\n public readonly authConfig: AuthConfig\n\n constructor(\n private readonly jwt: JwtService,\n private readonly config: ConfigService\n ) {\n this.authConfig = this.config.get<AuthConfig>('auth')\n }\n\n async getTokens(user: UserModel, refresh = false): Promise<TokenResponseDto> {\n const currentTime = currentTimeStamp()\n if (refresh && user.exp < currentTime) {\n this.logger.error(`${this.getTokens.name} - token refresh has incorrect expiration : *${user.login}*`)\n throw new HttpException('Token has expired', HttpStatus.FORBIDDEN)\n }\n const accessExpiration = convertHumanTimeToSeconds(this.authConfig.token.access.expiration)\n const refreshExpiration = refresh ? user.exp - currentTime : convertHumanTimeToSeconds(this.authConfig.token.refresh.expiration)\n return {\n [TOKEN_TYPE.ACCESS]: await this.jwtSign(user, TOKEN_TYPE.ACCESS, accessExpiration),\n [TOKEN_TYPE.REFRESH]: await this.jwtSign(user, TOKEN_TYPE.REFRESH, refreshExpiration),\n [`${TOKEN_TYPE.ACCESS}_expiration`]: accessExpiration + currentTime,\n [`${TOKEN_TYPE.REFRESH}_expiration`]: refreshExpiration + currentTime\n }\n }\n\n async setCookies(user: UserModel, res: FastifyReply): Promise<LoginResponseDto> {\n const response = new LoginResponseDto(user)\n const currentTime = currentTimeStamp()\n const csrfToken: string = crypto.randomUUID()\n for (const type of TOKEN_TYPES) {\n const tokenExpiration = convertHumanTimeToSeconds(this.authConfig.token[type].expiration)\n const cookieValue: string = type === TOKEN_TYPE.CSRF ? csrfToken : await this.jwtSign(user, type, tokenExpiration, csrfToken)\n res.setCookie(this.authConfig.token[type].name, cookieValue, {\n signed: type === TOKEN_TYPE.CSRF,\n path: TOKEN_PATHS[type],\n maxAge: convertHumanTimeToSeconds(this.authConfig.token[type].cookieMaxAge),\n httpOnly: type !== TOKEN_TYPE.CSRF\n })\n if (type === TOKEN_TYPE.ACCESS || type === TOKEN_TYPE.REFRESH) {\n response.token[`${type}_expiration`] = tokenExpiration + currentTime\n }\n }\n return response\n }\n\n async refreshCookies(user: UserModel, res: FastifyReply): Promise<TokenResponseDto> {\n const response = {} as TokenResponseDto\n const currentTime = currentTimeStamp()\n let refreshTokenExpiration: number\n let refreshMaxAge: number\n // refresh cookie must have the `exp` attribute\n // reuse token expiration to make it final\n if (user.exp && user.exp > currentTime) {\n refreshTokenExpiration = user.exp - currentTime\n refreshMaxAge = refreshTokenExpiration\n } else {\n this.logger.error(`${this.refreshCookies.name} - token ${TOKEN_TYPE.REFRESH} has incorrect expiration : *${user.login}*`)\n throw new HttpException('Token has expired', HttpStatus.FORBIDDEN)\n }\n const csrfToken: string = crypto.randomUUID()\n for (const type of TOKEN_TYPES) {\n const tokenExpiration = type === TOKEN_TYPE.REFRESH ? refreshTokenExpiration : convertHumanTimeToSeconds(this.authConfig.token[type].expiration)\n const maxAge = type === TOKEN_TYPE.REFRESH ? refreshMaxAge : convertHumanTimeToSeconds(this.authConfig.token[type].cookieMaxAge)\n const cookieValue: string = type === TOKEN_TYPE.CSRF ? csrfToken : await this.jwtSign(user, type, tokenExpiration, csrfToken)\n res.setCookie(this.authConfig.token[type].name, cookieValue, {\n signed: type === TOKEN_TYPE.CSRF,\n path: TOKEN_PATHS[type],\n maxAge: maxAge,\n httpOnly: type !== TOKEN_TYPE.CSRF\n })\n if (type === TOKEN_TYPE.ACCESS || type === TOKEN_TYPE.REFRESH) {\n response[`${type}_expiration`] = tokenExpiration + currentTime\n }\n }\n return response\n }\n\n async clearCookies(res: FastifyReply) {\n for (const [type, path] of Object.entries(TOKEN_PATHS)) {\n res.clearCookie(this.authConfig.token[type].name, { path: path, httpOnly: type !== TOKEN_TYPE.CSRF })\n }\n }\n\n private jwtSign(user: UserModel, type: TOKEN_TYPE, expiration: number, csrfToken?: string): Promise<string> {\n return this.jwt.signAsync(\n {\n identity: {\n id: user.id,\n login: user.login,\n email: user.email,\n fullName: user.fullName,\n role: user.role,\n applications: user.applications,\n impersonatedFromId: user.impersonatedFromId || undefined,\n impersonatedClientId: user.impersonatedClientId || undefined,\n clientId: user.clientId || undefined\n } satisfies JwtIdentityPayload,\n ...((type === TOKEN_TYPE.ACCESS || type === TOKEN_TYPE.REFRESH) && { csrf: csrfToken })\n },\n {\n secret: this.authConfig.token[type].secret,\n expiresIn: expiration\n }\n )\n }\n\n csrfValidation(req: FastifyRequest, jwtPayload: JwtPayload, type: TOKEN_TYPE.ACCESS | TOKEN_TYPE.REFRESH): void {\n // ignore safe methods\n if (HTTP_CSRF_IGNORED_METHODS.has(req.method)) {\n return\n }\n\n // check csrf only for access & refresh cookies\n if (typeof req.cookies !== 'object' || req.cookies[this.authConfig.token[type].name] === undefined) {\n return\n }\n\n if (!jwtPayload.csrf) {\n this.logger.warn(`${this.csrfValidation.name} - ${CSRF_ERROR.MISSING_JWT}`)\n throw new HttpException(CSRF_ERROR.MISSING_JWT, HttpStatus.FORBIDDEN)\n }\n\n if (!req.headers[CSRF_KEY]) {\n this.logger.warn(`${this.csrfValidation.name} - ${CSRF_ERROR.MISSING_HEADERS}`)\n throw new HttpException(CSRF_ERROR.MISSING_HEADERS, HttpStatus.FORBIDDEN)\n }\n\n const csrfHeader: UnsignResult = unsign(req.headers[CSRF_KEY] as string, this.authConfig.token.csrf.secret)\n if (jwtPayload.csrf !== csrfHeader.value) {\n this.logger.warn(`${this.csrfValidation.name} - ${CSRF_ERROR.MISMATCH}`)\n throw new HttpException(CSRF_ERROR.MISMATCH, HttpStatus.FORBIDDEN)\n }\n }\n}\n"],"names":["AuthManager","getTokens","user","refresh","currentTime","currentTimeStamp","exp","logger","error","name","login","HttpException","HttpStatus","FORBIDDEN","accessExpiration","convertHumanTimeToSeconds","authConfig","token","access","expiration","refreshExpiration","TOKEN_TYPE","ACCESS","jwtSign","REFRESH","setCookies","res","response","LoginResponseDto","csrfToken","crypto","randomUUID","type","TOKEN_TYPES","tokenExpiration","cookieValue","CSRF","setCookie","signed","path","TOKEN_PATHS","maxAge","cookieMaxAge","httpOnly","refreshCookies","refreshTokenExpiration","refreshMaxAge","clearCookies","Object","entries","clearCookie","jwt","signAsync","identity","id","email","fullName","role","applications","impersonatedFromId","undefined","impersonatedClientId","clientId","csrf","secret","expiresIn","csrfValidation","req","jwtPayload","HTTP_CSRF_IGNORED_METHODS","has","method","cookies","warn","CSRF_ERROR","MISSING_JWT","headers","CSRF_KEY","MISSING_HEADERS","csrfHeader","unsign","value","MISMATCH","config","Logger","get"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../backend/src/authentication/services/auth-manager.service.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\nimport { unsign, UnsignResult } from '@fastify/cookie'\nimport { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport { JwtService } from '@nestjs/jwt'\nimport { FastifyReply, FastifyRequest } from 'fastify'\nimport crypto from 'node:crypto'\nimport { HTTP_CSRF_IGNORED_METHODS } from '../../applications/applications.constants'\nimport { UserModel } from '../../applications/users/models/user.model'\nimport { convertHumanTimeToSeconds } from '../../common/functions'\nimport { currentTimeStamp } from '../../common/shared'\nimport { configuration, serverConfig } from '../../configuration/config.environment'\nimport { CSRF_ERROR, CSRF_KEY, TOKEN_2FA_TYPES, TOKEN_PATHS, TOKEN_TYPES } from '../constants/auth'\nimport { LoginResponseDto, LoginVerify2FaDto } from '../dto/login-response.dto'\nimport { TokenResponseDto } from '../dto/token-response.dto'\nimport { JwtIdentity2FaPayload, JwtIdentityPayload, JwtPayload } from '../interfaces/jwt-payload.interface'\nimport { TOKEN_TYPE } from '../interfaces/token.interface'\n\n@Injectable()\nexport class AuthManager {\n private readonly logger = new Logger(AuthManager.name)\n\n constructor(private readonly jwt: JwtService) {}\n\n async getTokens(user: UserModel, refresh = false): Promise<TokenResponseDto> {\n const currentTime = currentTimeStamp()\n if (refresh && user.exp < currentTime) {\n this.logger.error(`${this.getTokens.name} - token refresh has incorrect expiration : *${user.login}*`)\n throw new HttpException('Token has expired', HttpStatus.FORBIDDEN)\n }\n const accessExpiration = convertHumanTimeToSeconds(configuration.auth.token.access.expiration)\n const refreshExpiration = refresh ? user.exp - currentTime : convertHumanTimeToSeconds(configuration.auth.token.refresh.expiration)\n return {\n [TOKEN_TYPE.ACCESS]: await this.jwtSign(user, TOKEN_TYPE.ACCESS, accessExpiration),\n [TOKEN_TYPE.REFRESH]: await this.jwtSign(user, TOKEN_TYPE.REFRESH, refreshExpiration),\n [`${TOKEN_TYPE.ACCESS}_expiration`]: accessExpiration + currentTime,\n [`${TOKEN_TYPE.REFRESH}_expiration`]: refreshExpiration + currentTime\n }\n }\n\n async setCookies(user: UserModel, res: FastifyReply, init2FaVerify: true): Promise<LoginVerify2FaDto>\n async setCookies(user: UserModel, res: FastifyReply, init2FaVerify?: false): Promise<LoginResponseDto>\n async setCookies(user: UserModel, res: FastifyReply, init2FaVerify = false): Promise<LoginResponseDto | LoginVerify2FaDto> {\n // If `verify2Fa` is true, it sets the cookies and response required for valid 2FA authentication.\n const verify2Fa = init2FaVerify && configuration.auth.mfa.totp.enabled && user.twoFaEnabled\n const response = verify2Fa ? new LoginVerify2FaDto(serverConfig) : new LoginResponseDto(user, serverConfig)\n const currentTime = currentTimeStamp()\n const csrfToken: string = crypto.randomUUID()\n const tokenTypes: TOKEN_TYPE[] = verify2Fa ? TOKEN_2FA_TYPES : TOKEN_TYPES\n for (const type of tokenTypes) {\n const isCSRFToken = type === TOKEN_TYPE.CSRF || type === TOKEN_TYPE.CSRF_2FA\n const tokenExpiration = convertHumanTimeToSeconds(configuration.auth.token[type].expiration)\n let cookieValue: string\n if (isCSRFToken) {\n cookieValue = csrfToken\n } else if (verify2Fa) {\n cookieValue = await this.jwtSign2Fa(user, type, tokenExpiration, csrfToken)\n } else {\n cookieValue = await this.jwtSign(user, type, tokenExpiration, csrfToken)\n }\n res.setCookie(configuration.auth.token[type].name, cookieValue, {\n signed: isCSRFToken,\n path: TOKEN_PATHS[type],\n maxAge: tokenExpiration,\n httpOnly: !isCSRFToken\n })\n if (type === TOKEN_TYPE.ACCESS || type === TOKEN_TYPE.REFRESH || type === TOKEN_TYPE.ACCESS_2FA) {\n response.token[`${type}_expiration`] = tokenExpiration + currentTime\n }\n }\n return response\n }\n\n async refreshCookies(user: UserModel, res: FastifyReply): Promise<TokenResponseDto> {\n const response = {} as TokenResponseDto\n const currentTime = currentTimeStamp()\n let refreshTokenExpiration: number\n // refresh cookie must have the `exp` attribute\n // reuse token expiration to make it final\n if (user.exp && user.exp > currentTime) {\n refreshTokenExpiration = user.exp - currentTime\n } else {\n this.logger.error(`${this.refreshCookies.name} - token ${TOKEN_TYPE.REFRESH} has incorrect expiration : *${user.login}*`)\n throw new HttpException('Token has expired', HttpStatus.FORBIDDEN)\n }\n const csrfToken: string = crypto.randomUUID()\n for (const type of TOKEN_TYPES) {\n const tokenExpiration =\n type === TOKEN_TYPE.ACCESS ? convertHumanTimeToSeconds(configuration.auth.token[TOKEN_TYPE.ACCESS].expiration) : refreshTokenExpiration\n const cookieValue: string = type === TOKEN_TYPE.CSRF ? csrfToken : await this.jwtSign(user, type, tokenExpiration, csrfToken)\n res.setCookie(configuration.auth.token[type].name, cookieValue, {\n signed: type === TOKEN_TYPE.CSRF,\n path: TOKEN_PATHS[type],\n maxAge: tokenExpiration,\n httpOnly: type !== TOKEN_TYPE.CSRF\n })\n if (type === TOKEN_TYPE.ACCESS || type === TOKEN_TYPE.REFRESH) {\n response[`${type}_expiration`] = tokenExpiration + currentTime\n }\n }\n return response\n }\n\n async clearCookies(res: FastifyReply) {\n for (const [type, path] of Object.entries(TOKEN_PATHS)) {\n res.clearCookie(configuration.auth.token[type].name, { path: path, httpOnly: type !== TOKEN_TYPE.CSRF })\n }\n }\n\n csrfValidation(req: FastifyRequest, jwtPayload: JwtPayload, type: TOKEN_TYPE.ACCESS | TOKEN_TYPE.REFRESH): void {\n // ignore safe methods\n if (HTTP_CSRF_IGNORED_METHODS.has(req.method)) {\n return\n }\n\n // check csrf only for access and refresh cookies\n if (typeof req.cookies !== 'object' || req.cookies[configuration.auth.token[type].name] === undefined) {\n return\n }\n\n if (!jwtPayload.csrf) {\n this.logger.warn(`${this.csrfValidation.name} - ${CSRF_ERROR.MISSING_JWT}`)\n throw new HttpException(CSRF_ERROR.MISSING_JWT, HttpStatus.FORBIDDEN)\n }\n\n if (!req.headers[CSRF_KEY]) {\n this.logger.warn(`${this.csrfValidation.name} - ${CSRF_ERROR.MISSING_HEADERS}`)\n throw new HttpException(CSRF_ERROR.MISSING_HEADERS, HttpStatus.FORBIDDEN)\n }\n\n const csrfHeader: UnsignResult = unsign(req.headers[CSRF_KEY] as string, configuration.auth.token.csrf.secret)\n if (jwtPayload.csrf !== csrfHeader.value) {\n this.logger.warn(`${this.csrfValidation.name} - ${CSRF_ERROR.MISMATCH}`)\n throw new HttpException(CSRF_ERROR.MISMATCH, HttpStatus.FORBIDDEN)\n }\n }\n\n private jwtSign(user: UserModel, type: TOKEN_TYPE, expiration: number, csrfToken?: string): Promise<string> {\n return this.jwt.signAsync(\n {\n identity: {\n id: user.id,\n login: user.login,\n email: user.email,\n fullName: user.fullName,\n language: user.language,\n role: user.role,\n applications: user.applications,\n impersonatedFromId: user.impersonatedFromId || undefined,\n impersonatedClientId: user.impersonatedClientId || undefined,\n clientId: user.clientId || undefined,\n twoFaEnabled: user.twoFaEnabled || undefined\n } satisfies JwtIdentityPayload,\n ...((type === TOKEN_TYPE.ACCESS || type === TOKEN_TYPE.REFRESH) && { csrf: csrfToken })\n },\n {\n secret: configuration.auth.token[type].secret,\n expiresIn: expiration\n }\n )\n }\n\n private jwtSign2Fa(user: UserModel, type: TOKEN_TYPE, expiration: number, csrfToken: string): Promise<string> {\n // Restrict the temporary token to the minimum required information\n return this.jwt.signAsync(\n {\n identity: {\n id: user.id,\n login: user.login,\n language: user.language,\n role: user.role,\n twoFaEnabled: true\n } satisfies JwtIdentity2FaPayload,\n csrf: csrfToken\n },\n {\n secret: configuration.auth.token[type].secret,\n expiresIn: expiration\n }\n )\n }\n}\n"],"names":["AuthManager","getTokens","user","refresh","currentTime","currentTimeStamp","exp","logger","error","name","login","HttpException","HttpStatus","FORBIDDEN","accessExpiration","convertHumanTimeToSeconds","configuration","auth","token","access","expiration","refreshExpiration","TOKEN_TYPE","ACCESS","jwtSign","REFRESH","setCookies","res","init2FaVerify","verify2Fa","mfa","totp","enabled","twoFaEnabled","response","LoginVerify2FaDto","serverConfig","LoginResponseDto","csrfToken","crypto","randomUUID","tokenTypes","TOKEN_2FA_TYPES","TOKEN_TYPES","type","isCSRFToken","CSRF","CSRF_2FA","tokenExpiration","cookieValue","jwtSign2Fa","setCookie","signed","path","TOKEN_PATHS","maxAge","httpOnly","ACCESS_2FA","refreshCookies","refreshTokenExpiration","clearCookies","Object","entries","clearCookie","csrfValidation","req","jwtPayload","HTTP_CSRF_IGNORED_METHODS","has","method","cookies","undefined","csrf","warn","CSRF_ERROR","MISSING_JWT","headers","CSRF_KEY","MISSING_HEADERS","csrfHeader","unsign","secret","value","MISMATCH","jwt","signAsync","identity","id","email","fullName","language","role","applications","impersonatedFromId","impersonatedClientId","clientId","expiresIn","Logger"],"mappings":"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"}
|
|
@@ -25,19 +25,19 @@ function _ts_metadata(k, v) {
|
|
|
25
25
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
26
26
|
}
|
|
27
27
|
let AuthMethodDatabase = class AuthMethodDatabase {
|
|
28
|
-
async validateUser(loginOrEmail, password, ip) {
|
|
28
|
+
async validateUser(loginOrEmail, password, ip, scope) {
|
|
29
29
|
let user;
|
|
30
30
|
try {
|
|
31
31
|
user = await this.usersManager.findUser(loginOrEmail, false);
|
|
32
32
|
} catch (e) {
|
|
33
33
|
this.logger.error(`${this.validateUser.name} - ${e}`);
|
|
34
|
-
throw new _common.HttpException(_appconstants.CONNECT_ERROR_CODE.has(e.cause?.code) ? 'Authentication service error' : e.message, _common.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
34
|
+
throw new _common.HttpException(_appconstants.CONNECT_ERROR_CODE.has(e.cause?.code) ? 'Authentication service error' : e.cause?.code || e.message, _common.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
35
35
|
}
|
|
36
36
|
if (!user) {
|
|
37
37
|
this.logger.warn(`${this.validateUser.name} - login or email not found for *${loginOrEmail}*`);
|
|
38
38
|
return null;
|
|
39
39
|
}
|
|
40
|
-
return await this.usersManager.logUser(user, password, ip);
|
|
40
|
+
return await this.usersManager.logUser(user, password, ip, scope);
|
|
41
41
|
}
|
|
42
42
|
constructor(usersManager){
|
|
43
43
|
this.usersManager = usersManager;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/authentication/services/auth-methods/auth-method-database.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 } from '@nestjs/common'\nimport { CONNECT_ERROR_CODE } from '../../../app.constants'\nimport { UserModel } from '../../../applications/users/models/user.model'\nimport { UsersManager } from '../../../applications/users/services/users-manager.service'\nimport { AuthMethod } from '../../models/auth-method'\n\n@Injectable()\nexport class AuthMethodDatabase implements AuthMethod {\n private readonly logger = new Logger(AuthMethodDatabase.name)\n\n constructor(private readonly usersManager: UsersManager) {}\n\n async validateUser(loginOrEmail: string, password: string, ip?: string): Promise<UserModel> {\n let user: UserModel\n try {\n user = await this.usersManager.findUser(loginOrEmail, false)\n } catch (e) {\n this.logger.error(`${this.validateUser.name} - ${e}`)\n throw new HttpException(CONNECT_ERROR_CODE.has(e.cause?.code) ? 'Authentication service error' : e.message
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/authentication/services/auth-methods/auth-method-database.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 } from '@nestjs/common'\nimport { CONNECT_ERROR_CODE } from '../../../app.constants'\nimport { UserModel } from '../../../applications/users/models/user.model'\nimport { UsersManager } from '../../../applications/users/services/users-manager.service'\nimport { AUTH_SCOPE } from '../../constants/scope'\nimport { AuthMethod } from '../../models/auth-method'\n\n@Injectable()\nexport class AuthMethodDatabase implements AuthMethod {\n private readonly logger = new Logger(AuthMethodDatabase.name)\n\n constructor(private readonly usersManager: UsersManager) {}\n\n async validateUser(loginOrEmail: string, password: string, ip?: string, scope?: AUTH_SCOPE): Promise<UserModel> {\n let user: UserModel\n try {\n user = await this.usersManager.findUser(loginOrEmail, false)\n } catch (e) {\n this.logger.error(`${this.validateUser.name} - ${e}`)\n throw new HttpException(\n CONNECT_ERROR_CODE.has(e.cause?.code) ? 'Authentication service error' : e.cause?.code || e.message,\n HttpStatus.INTERNAL_SERVER_ERROR\n )\n }\n if (!user) {\n this.logger.warn(`${this.validateUser.name} - login or email not found for *${loginOrEmail}*`)\n return null\n }\n return await this.usersManager.logUser(user, password, ip, scope)\n }\n}\n"],"names":["AuthMethodDatabase","validateUser","loginOrEmail","password","ip","scope","user","usersManager","findUser","e","logger","error","name","HttpException","CONNECT_ERROR_CODE","has","cause","code","message","HttpStatus","INTERNAL_SERVER_ERROR","warn","logUser","Logger"],"mappings":"AAAA;;;;CAIC;;;;+BAUYA;;;eAAAA;;;wBARiD;8BAC3B;qCAEN;;;;;;;;;;AAKtB,IAAA,AAAMA,qBAAN,MAAMA;IAKX,MAAMC,aAAaC,YAAoB,EAAEC,QAAgB,EAAEC,EAAW,EAAEC,KAAkB,EAAsB;QAC9G,IAAIC;QACJ,IAAI;YACFA,OAAO,MAAM,IAAI,CAACC,YAAY,CAACC,QAAQ,CAACN,cAAc;QACxD,EAAE,OAAOO,GAAG;YACV,IAAI,CAACC,MAAM,CAACC,KAAK,CAAC,GAAG,IAAI,CAACV,YAAY,CAACW,IAAI,CAAC,GAAG,EAAEH,GAAG;YACpD,MAAM,IAAII,qBAAa,CACrBC,gCAAkB,CAACC,GAAG,CAACN,EAAEO,KAAK,EAAEC,QAAQ,iCAAiCR,EAAEO,KAAK,EAAEC,QAAQR,EAAES,OAAO,EACnGC,kBAAU,CAACC,qBAAqB;QAEpC;QACA,IAAI,CAACd,MAAM;YACT,IAAI,CAACI,MAAM,CAACW,IAAI,CAAC,GAAG,IAAI,CAACpB,YAAY,CAACW,IAAI,CAAC,iCAAiC,EAAEV,aAAa,CAAC,CAAC;YAC7F,OAAO;QACT;QACA,OAAO,MAAM,IAAI,CAACK,YAAY,CAACe,OAAO,CAAChB,MAAMH,UAAUC,IAAIC;IAC7D;IAlBA,YAAY,AAAiBE,YAA0B,CAAE;aAA5BA,eAAAA;aAFZG,SAAS,IAAIa,cAAM,CAACvB,mBAAmBY,IAAI;IAEF;AAmB5D"}
|
|
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
8
8
|
});
|
|
9
9
|
const _testing = require("@nestjs/testing");
|
|
10
10
|
const _appconstants = require("../../../app.constants");
|
|
11
|
+
const _notificationsmanagerservice = require("../../../applications/notifications/services/notifications-manager.service");
|
|
11
12
|
const _usermodel = require("../../../applications/users/models/user.model");
|
|
12
13
|
const _adminusersmanagerservice = require("../../../applications/users/services/admin-users-manager.service");
|
|
13
14
|
const _adminusersqueriesservice = require("../../../applications/users/services/admin-users-queries.service");
|
|
@@ -42,6 +43,10 @@ describe(_authmethoddatabaseservice.AuthMethodDatabase.name, ()=>{
|
|
|
42
43
|
{
|
|
43
44
|
provide: _cacheservice.Cache,
|
|
44
45
|
useValue: {}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
provide: _notificationsmanagerservice.NotificationsManager,
|
|
49
|
+
useValue: {}
|
|
45
50
|
}
|
|
46
51
|
]
|
|
47
52
|
}).compile();
|