@sync-in/server 1.3.9 → 1.4.0
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 +15 -0
- package/README.md +3 -2
- package/environment/environment.dist.yaml +2 -0
- package/package.json +2 -2
- package/server/app.bootstrap.js +9 -0
- package/server/app.bootstrap.js.map +1 -1
- package/server/app.service.spec.js +44 -19
- package/server/app.service.spec.js.map +1 -1
- package/server/applications/files/constants/files.js +0 -23
- package/server/applications/files/constants/files.js.map +1 -1
- package/server/applications/files/constants/only-office.js +8 -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/guards/files-only-office.strategy.js +0 -1
- package/server/applications/files/guards/files-only-office.strategy.js.map +1 -1
- package/server/applications/spaces/guards/space.guard.spec.js +153 -18
- package/server/applications/spaces/guards/space.guard.spec.js.map +1 -1
- package/server/applications/spaces/services/spaces-browser.service.js +7 -7
- package/server/applications/spaces/services/spaces-browser.service.js.map +1 -1
- package/server/applications/spaces/services/spaces-manager.service.js +17 -17
- package/server/applications/spaces/services/spaces-manager.service.js.map +1 -1
- package/server/applications/sync/utils/routes.js +1 -1
- package/server/applications/sync/utils/routes.js.map +1 -1
- package/server/applications/users/guards/permissions.guard.js +4 -4
- package/server/applications/users/guards/permissions.guard.js.map +1 -1
- package/server/applications/users/guards/permissions.guard.spec.js +6 -6
- package/server/applications/users/guards/permissions.guard.spec.js.map +1 -1
- package/server/applications/users/guards/roles.guard.js +1 -1
- package/server/applications/users/guards/roles.guard.js.map +1 -1
- package/server/applications/users/models/user.model.js +1 -1
- package/server/applications/users/models/user.model.js.map +1 -1
- package/server/authentication/guards/auth-basic.guard.spec.js +38 -2
- package/server/authentication/guards/auth-basic.guard.spec.js.map +1 -1
- package/server/authentication/guards/auth-basic.strategy.js +0 -1
- package/server/authentication/guards/auth-basic.strategy.js.map +1 -1
- package/server/authentication/guards/auth-local.guard.spec.js +7 -5
- package/server/authentication/guards/auth-local.guard.spec.js.map +1 -1
- package/server/authentication/guards/auth-local.strategy.js +0 -1
- package/server/authentication/guards/auth-local.strategy.js.map +1 -1
- package/server/authentication/guards/auth-token-access.guard.spec.js +30 -0
- package/server/authentication/guards/auth-token-access.guard.spec.js.map +1 -1
- package/server/authentication/guards/auth-token-access.strategy.js +0 -1
- package/server/authentication/guards/auth-token-access.strategy.js.map +1 -1
- package/server/authentication/guards/auth-token-refresh.strategy.js +0 -1
- package/server/authentication/guards/auth-token-refresh.strategy.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-database.service.js +1 -1
- 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 +8 -6
- 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 +2 -2
- 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 +500 -5
- package/server/authentication/services/auth-methods/auth-method-ldap.service.spec.js.map +1 -1
- package/server/configuration/config.loader.js +0 -3
- package/server/configuration/config.loader.js.map +1 -1
- package/server/infrastructure/context/services/context-manager.service.spec.js +98 -0
- package/server/infrastructure/context/services/context-manager.service.spec.js.map +1 -0
- package/server/infrastructure/database/constants.js +0 -1
- package/server/infrastructure/database/constants.js.map +1 -1
- package/server/infrastructure/database/scripts/seed/usersgroups.js +3 -3
- package/server/infrastructure/database/scripts/seed/usersgroups.js.map +1 -1
- package/server/infrastructure/mailer/mailer.service.js +20 -19
- package/server/infrastructure/mailer/mailer.service.js.map +1 -1
- package/server/infrastructure/mailer/mailer.service.spec.js +176 -0
- package/server/infrastructure/mailer/mailer.service.spec.js.map +1 -0
- package/static/{chunk-KFM544CA.js → chunk-3GC2BQZD.js} +1 -1
- package/static/{chunk-MWFRZBJD.js → chunk-5YKWZT33.js} +1 -1
- package/static/{chunk-XUZSYWRF.js → chunk-6F55D74O.js} +1 -1
- package/static/{chunk-ZFKCGL6X.js → chunk-B2Y2RNFP.js} +1 -1
- package/static/{chunk-PYSFXLMV.js → chunk-C23BPTJZ.js} +1 -1
- package/static/{chunk-FJFNDK67.js → chunk-DGVNNICG.js} +1 -1
- package/static/{chunk-SRLMFJ7C.js → chunk-FQ4AFNGE.js} +1 -1
- package/static/{chunk-Z5X7LVMZ.js → chunk-GBCYYDCI.js} +1 -1
- package/static/{chunk-MK7WZG3F.js → chunk-HZA7R43P.js} +1 -1
- package/static/{chunk-HUWQHCUX.js → chunk-KZQCFEPT.js} +1 -1
- package/static/{chunk-S5WXHO6D.js → chunk-LJIGRUEF.js} +1 -1
- package/static/{chunk-4KESSWTF.js → chunk-MOVWEZ7J.js} +1 -1
- package/static/{chunk-LYTD6AJE.js → chunk-N2LYWNTC.js} +1 -1
- package/static/{chunk-NV2MEIWP.js → chunk-PF4K7MVG.js} +1 -1
- package/static/{chunk-SKDQM65G.js → chunk-PY3BGNJN.js} +1 -1
- package/static/{chunk-QTW62OKJ.js → chunk-T55FAU2O.js} +1 -1
- package/static/{chunk-N3T57OCA.js → chunk-TCFKH6K6.js} +1 -1
- package/static/{chunk-3FX6ISDY.js → chunk-TDQAEVZN.js} +1 -1
- package/static/{chunk-O4AQBQBF.js → chunk-TNW2CGK6.js} +1 -1
- package/static/{chunk-3S4WNZ2T.js → chunk-TXPODW5Q.js} +1 -1
- package/static/{chunk-BW5PQAKK.js → chunk-VHYIXL7R.js} +1 -1
- package/static/{chunk-CLSVDV7J.js → chunk-VMQMD36Z.js} +1 -1
- package/static/{chunk-O67RFAWU.js → chunk-VMUOUCEI.js} +1 -1
- package/static/{chunk-WLPYIJFI.js → chunk-W3QXNDI5.js} +1 -1
- package/static/{chunk-AY2GOSJ2.js → chunk-WHMS3PJ3.js} +1 -1
- package/static/{chunk-4TEHM3AS.js → chunk-WWIC7UW3.js} +1 -1
- package/static/{chunk-LB7B5RIV.js → chunk-X43VWRFP.js} +1 -1
- package/static/{chunk-WL65GYD5.js → chunk-Y2CDUS4J.js} +2 -2
- package/static/{chunk-ZTXJC5IC.js → chunk-YCINY2YI.js} +1 -1
- package/static/index.html +2 -2
- package/static/{main-RREKR34B.js → main-7LDKYVXO.js} +3 -3
- package/static/styles-FYUSO6OJ.css +1 -0
- package/static/styles-3DONJ2Z4.css +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
|
|
2
|
+
## [1.4.0](https://github.com/Sync-in/server/compare/v1.3.9...v1.4.0) (2025-08-26)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* **backend:webdav:** add temporary hook for Joplin sync compatibility (laurent22/joplin[#12249](https://github.com/Sync-in/server/issues/12249)) ([fc22a7d](https://github.com/Sync-in/server/commit/fc22a7d828f99abe65423d03418fe397ab45d7b0))
|
|
8
|
+
* **backend:files:** add showHiddenFiles option to toggle visibility of dotfiles ([ed47fbf](https://github.com/Sync-in/server/commit/ed47fbf3fe7fe5b66868489c319d3c438fde0dbf))
|
|
9
|
+
* **backend:files:** allow markdown files to be edited with onlyOffice ([c3d9d85](https://github.com/Sync-in/server/commit/c3d9d85d3f1dc90f4afae8db8ce9d128c8ecadf2))
|
|
10
|
+
* **frontend:spaces:** open documents in edit mode on double-click ([d6ef175](https://github.com/Sync-in/server/commit/d6ef175d951b4e11ce78d280e4982e3ed8a4bb3f))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **backend:users:** ensure permission guards correctly evaluate array permissions ([c27dc7b](https://github.com/Sync-in/server/commit/c27dc7b7ac20293febca17d18ae8608d61eb1b44))
|
|
16
|
+
|
|
2
17
|
## [1.3.9](https://github.com/Sync-in/server/compare/v1.3.8...v1.3.9) (2025-08-22)
|
|
3
18
|
|
|
4
19
|
|
package/README.md
CHANGED
|
@@ -14,9 +14,10 @@ _Welcome to the official Sync-in server repository!_
|
|
|
14
14
|
- 📦 [Deploy with NPM](https://sync-in.com/docs/setup-guide/npm)
|
|
15
15
|
|
|
16
16
|
<a href="#-license"><img src="https://img.shields.io/badge/Licence-AGPL%20v3.0-green.svg" alt="License"/></a>
|
|
17
|
-
<a href="https://
|
|
18
|
-
<a href="https://www.npmjs.com/package/@sync-in/server" target="_blank"><img src="https://img.shields.io/npm/d18m/@sync-in/server.svg?logo=npm&label=NPM%20Downloads&color=cb3837" alt="NPM"/></a>
|
|
17
|
+
<a href="https://github.com/Sync-in/server/releases" target="_blank"><img src="https://img.shields.io/github/v/release/Sync-in/server?sort=semver&display_name=tag&style=flat&logo=github&label=Release" alt="GitHub Release"/></a>
|
|
19
18
|
<a href="https://hub.docker.com/r/syncin/server" target="_blank"><img src="https://img.shields.io/docker/pulls/syncin/server?logo=docker&label=Docker%20Hub%20Pulls" alt="Docker pulls"/></a>
|
|
19
|
+
<a href="https://www.npmjs.com/package/@sync-in/server" target="_blank"><img src="https://img.shields.io/npm/d18m/@sync-in/server.svg?logo=npm&label=NPM%20Downloads&color=cb3837" alt="NPM"/></a>
|
|
20
|
+
<a href="https://discord.gg/qhJyzwaymT" target="_blank"><img src="https://img.shields.io/discord/1391081837849346088?logo=discord&label=Discord" alt="Discord"/></a>
|
|
20
21
|
|
|
21
22
|
The **Sync-in Server** is designed to run on your own infrastructure, it gives you **full control over your data** while offering a modern,
|
|
22
23
|
intuitive interface for both internal and external users.
|
|
@@ -81,6 +81,8 @@ applications:
|
|
|
81
81
|
dataPath: /home/sync-in
|
|
82
82
|
# Default to 5 GB if not specified
|
|
83
83
|
maxUploadSize: 5368709120
|
|
84
|
+
# Show files starting with a dot in the file explorer (default: false)
|
|
85
|
+
showHiddenFiles: false
|
|
84
86
|
onlyoffice:
|
|
85
87
|
enabled: false
|
|
86
88
|
# for an external server (e.g: https://onlyoffice.domain.com), remember the url must be accessible from browser !
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sync-in/server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "The secure, open-source platform for file storage, sharing, collaboration, and sync",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Johan Legrand",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"class-validator": "0.14.2",
|
|
99
99
|
"deepmerge": "4.3.1",
|
|
100
100
|
"drizzle-kit": "0.31.4",
|
|
101
|
-
"drizzle-orm": "0.44.
|
|
101
|
+
"drizzle-orm": "0.44.5",
|
|
102
102
|
"fast-xml-parser": "5.2.5",
|
|
103
103
|
"fs-extra": "11.3.1",
|
|
104
104
|
"html-to-text": "9.0.5",
|
package/server/app.bootstrap.js
CHANGED
|
@@ -22,6 +22,7 @@ const _nestjspino = require("nestjs-pino");
|
|
|
22
22
|
const _appconstants = require("./app.constants");
|
|
23
23
|
const _appmodule = require("./app.module");
|
|
24
24
|
const _applicationsconstants = require("./applications/applications.constants");
|
|
25
|
+
const _routes = require("./applications/webdav/constants/routes");
|
|
25
26
|
const _configconstants = require("./configuration/config.constants");
|
|
26
27
|
const _configenvironment = require("./configuration/config.environment");
|
|
27
28
|
const _websocketadapter = require("./infrastructure/websocket/adapters/web-socket.adapter");
|
|
@@ -60,6 +61,14 @@ async function appBootstrap() {
|
|
|
60
61
|
fastifyInstance.addContentTypeParser('*', {
|
|
61
62
|
bodyLimit: 0
|
|
62
63
|
}, (_req, _payload, done)=>done(null));
|
|
64
|
+
// Joplin clients send incorrect `Content-Type` headers when syncing over WebDAV (issue: https://github.com/laurent22/joplin/issues/122499)
|
|
65
|
+
// This hook intercepts matching requests and sets `application/octet-stream` to ensure compatibility and successful sync.
|
|
66
|
+
// todo: remove it when fixed on Joplin side
|
|
67
|
+
fastifyInstance.addHook('onRequest', async (req, _reply)=>{
|
|
68
|
+
if ((req.headers['user-agent'] || '').indexOf('Joplin') !== -1 && req.originalUrl.startsWith(_routes.WEBDAV_SPACES[_routes.WEBDAV_NS.WEBDAV].route)) {
|
|
69
|
+
req.headers['content-type'] = 'application/octet-stream';
|
|
70
|
+
}
|
|
71
|
+
});
|
|
63
72
|
/* INTERCEPTORS */ app.useGlobalInterceptors(new _nestjspino.LoggerErrorInterceptor(), new _common.ClassSerializerInterceptor(app.get(_core.Reflector), {
|
|
64
73
|
excludePrefixes: [
|
|
65
74
|
'_'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../backend/src/app.bootstrap.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 fastifyCookie from '@fastify/cookie'\nimport fastifyHelmet from '@fastify/helmet'\nimport multipart from '@fastify/multipart'\nimport { ClassSerializerInterceptor, ValidationPipe } from '@nestjs/common'\nimport { NestFactory, Reflector } from '@nestjs/core'\nimport { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'\nimport { FastifyRequest } from 'fastify'\nimport { Logger, LoggerErrorInterceptor } from 'nestjs-pino'\nimport { CONTENT_SECURITY_POLICY } from './app.constants'\nimport { AppModule } from './app.module'\nimport { HTTP_WEBDAV_METHOD } from './applications/applications.constants'\nimport { IS_TEST_ENV, STATIC_PATH } from './configuration/config.constants'\nimport { configuration } from './configuration/config.environment'\nimport { WebSocketAdapter } from './infrastructure/websocket/adapters/web-socket.adapter'\n\nexport async function appBootstrap(): Promise<NestFastifyApplication> {\n /* APP */\n const fastifyAdapter = new FastifyAdapter({\n logger: false,\n trustProxy: configuration.server.trustProxy,\n ignoreTrailingSlash: true,\n maxParamLength: 256,\n bodyLimit: 26214400 /* 25 MB */\n })\n const app: NestFastifyApplication = await NestFactory.create<NestFastifyApplication>(AppModule, fastifyAdapter, {\n bufferLogs: true\n })\n\n /* Fastify instance */\n const fastifyInstance = fastifyAdapter.getInstance()\n\n /* LOGGER */\n app.useLogger(IS_TEST_ENV ? ['fatal'] : app.get(Logger))\n\n /* PARSER */\n // xml body parser is used for webdav methods\n app.useBodyParser(['application/xml', 'text/xml'])\n // add webdav methods\n for (const method of Object.values(HTTP_WEBDAV_METHOD)) {\n fastifyInstance.addHttpMethod(method, { hasBody: true })\n }\n // '*' body parser allow binary data as stream (unlimited body size)\n fastifyInstance.addContentTypeParser('*', { bodyLimit: 0 }, (_req: FastifyRequest, _payload: FastifyRequest['raw'], done) => done(null))\n\n /* INTERCEPTORS */\n app.useGlobalInterceptors(\n new LoggerErrorInterceptor(),\n new ClassSerializerInterceptor(app.get(Reflector), {\n excludePrefixes: ['_']\n })\n )\n /* VALIDATION */\n app.useGlobalPipes(new ValidationPipe({ transform: true, whitelist: true }))\n\n /* STATIC */\n app.useStaticAssets({ root: STATIC_PATH, prefixAvoidTrailingSlash: true })\n\n /* SECURITY */\n await app.register(fastifyHelmet, { contentSecurityPolicy: CONTENT_SECURITY_POLICY(configuration.applications.files.onlyoffice.externalServer) })\n\n /* COOKIES */\n // we use csrf secret to unsign csrf cookie\n await app.register(fastifyCookie, {\n secret: configuration.auth.token.csrf.secret,\n parseOptions: {\n secure: 'auto',\n sameSite: configuration.auth.sameSite,\n httpOnly: true\n }\n })\n\n /* UPLOAD */\n await app.register(multipart, {\n preservePath: true,\n limits: { parts: Infinity, fileSize: configuration.applications.files.maxUploadSize }\n })\n\n /* WEBSOCKET */\n if (!IS_TEST_ENV) {\n const webSocketAdapter = new WebSocketAdapter(app)\n await webSocketAdapter.initAdapter()\n app.useWebSocketAdapter(webSocketAdapter)\n }\n\n return app\n}\n"],"names":["appBootstrap","fastifyAdapter","FastifyAdapter","logger","trustProxy","configuration","server","ignoreTrailingSlash","maxParamLength","bodyLimit","app","NestFactory","create","AppModule","bufferLogs","fastifyInstance","getInstance","useLogger","IS_TEST_ENV","get","Logger","useBodyParser","method","Object","values","HTTP_WEBDAV_METHOD","addHttpMethod","hasBody","addContentTypeParser","_req","_payload","done","useGlobalInterceptors","LoggerErrorInterceptor","ClassSerializerInterceptor","Reflector","excludePrefixes","useGlobalPipes","ValidationPipe","transform","whitelist","useStaticAssets","root","STATIC_PATH","prefixAvoidTrailingSlash","register","fastifyHelmet","contentSecurityPolicy","CONTENT_SECURITY_POLICY","applications","files","onlyoffice","externalServer","fastifyCookie","secret","auth","token","csrf","parseOptions","secure","sameSite","httpOnly","multipart","preservePath","limits","parts","Infinity","fileSize","maxUploadSize","webSocketAdapter","WebSocketAdapter","initAdapter","useWebSocketAdapter"],"mappings":"AAAA;;;;CAIC;;;;+
|
|
1
|
+
{"version":3,"sources":["../../backend/src/app.bootstrap.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 fastifyCookie from '@fastify/cookie'\nimport fastifyHelmet from '@fastify/helmet'\nimport multipart from '@fastify/multipart'\nimport { ClassSerializerInterceptor, ValidationPipe } from '@nestjs/common'\nimport { NestFactory, Reflector } from '@nestjs/core'\nimport { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'\nimport { FastifyRequest } from 'fastify'\nimport { Logger, LoggerErrorInterceptor } from 'nestjs-pino'\nimport { CONTENT_SECURITY_POLICY } from './app.constants'\nimport { AppModule } from './app.module'\nimport { HTTP_WEBDAV_METHOD } from './applications/applications.constants'\nimport { WEBDAV_NS, WEBDAV_SPACES } from './applications/webdav/constants/routes'\nimport { IS_TEST_ENV, STATIC_PATH } from './configuration/config.constants'\nimport { configuration } from './configuration/config.environment'\nimport { WebSocketAdapter } from './infrastructure/websocket/adapters/web-socket.adapter'\n\nexport async function appBootstrap(): Promise<NestFastifyApplication> {\n /* APP */\n const fastifyAdapter = new FastifyAdapter({\n logger: false,\n trustProxy: configuration.server.trustProxy,\n ignoreTrailingSlash: true,\n maxParamLength: 256,\n bodyLimit: 26214400 /* 25 MB */\n })\n const app: NestFastifyApplication = await NestFactory.create<NestFastifyApplication>(AppModule, fastifyAdapter, {\n bufferLogs: true\n })\n\n /* Fastify instance */\n const fastifyInstance = fastifyAdapter.getInstance()\n\n /* LOGGER */\n app.useLogger(IS_TEST_ENV ? ['fatal'] : app.get(Logger))\n\n /* PARSER */\n // xml body parser is used for webdav methods\n app.useBodyParser(['application/xml', 'text/xml'])\n // add webdav methods\n for (const method of Object.values(HTTP_WEBDAV_METHOD)) {\n fastifyInstance.addHttpMethod(method, { hasBody: true })\n }\n // '*' body parser allow binary data as stream (unlimited body size)\n fastifyInstance.addContentTypeParser('*', { bodyLimit: 0 }, (_req: FastifyRequest, _payload: FastifyRequest['raw'], done) => done(null))\n\n // Joplin clients send incorrect `Content-Type` headers when syncing over WebDAV (issue: https://github.com/laurent22/joplin/issues/122499)\n // This hook intercepts matching requests and sets `application/octet-stream` to ensure compatibility and successful sync.\n // todo: remove it when fixed on Joplin side\n fastifyInstance.addHook('onRequest', async (req, _reply) => {\n if ((req.headers['user-agent'] || '').indexOf('Joplin') !== -1 && req.originalUrl.startsWith(WEBDAV_SPACES[WEBDAV_NS.WEBDAV].route)) {\n req.headers['content-type'] = 'application/octet-stream'\n }\n })\n\n /* INTERCEPTORS */\n app.useGlobalInterceptors(\n new LoggerErrorInterceptor(),\n new ClassSerializerInterceptor(app.get(Reflector), {\n excludePrefixes: ['_']\n })\n )\n /* VALIDATION */\n app.useGlobalPipes(new ValidationPipe({ transform: true, whitelist: true }))\n\n /* STATIC */\n app.useStaticAssets({ root: STATIC_PATH, prefixAvoidTrailingSlash: true })\n\n /* SECURITY */\n await app.register(fastifyHelmet, { contentSecurityPolicy: CONTENT_SECURITY_POLICY(configuration.applications.files.onlyoffice.externalServer) })\n\n /* COOKIES */\n // we use csrf secret to unsign csrf cookie\n await app.register(fastifyCookie, {\n secret: configuration.auth.token.csrf.secret,\n parseOptions: {\n secure: 'auto',\n sameSite: configuration.auth.sameSite,\n httpOnly: true\n }\n })\n\n /* UPLOAD */\n await app.register(multipart, {\n preservePath: true,\n limits: { parts: Infinity, fileSize: configuration.applications.files.maxUploadSize }\n })\n\n /* WEBSOCKET */\n if (!IS_TEST_ENV) {\n const webSocketAdapter = new WebSocketAdapter(app)\n await webSocketAdapter.initAdapter()\n app.useWebSocketAdapter(webSocketAdapter)\n }\n\n return app\n}\n"],"names":["appBootstrap","fastifyAdapter","FastifyAdapter","logger","trustProxy","configuration","server","ignoreTrailingSlash","maxParamLength","bodyLimit","app","NestFactory","create","AppModule","bufferLogs","fastifyInstance","getInstance","useLogger","IS_TEST_ENV","get","Logger","useBodyParser","method","Object","values","HTTP_WEBDAV_METHOD","addHttpMethod","hasBody","addContentTypeParser","_req","_payload","done","addHook","req","_reply","headers","indexOf","originalUrl","startsWith","WEBDAV_SPACES","WEBDAV_NS","WEBDAV","route","useGlobalInterceptors","LoggerErrorInterceptor","ClassSerializerInterceptor","Reflector","excludePrefixes","useGlobalPipes","ValidationPipe","transform","whitelist","useStaticAssets","root","STATIC_PATH","prefixAvoidTrailingSlash","register","fastifyHelmet","contentSecurityPolicy","CONTENT_SECURITY_POLICY","applications","files","onlyoffice","externalServer","fastifyCookie","secret","auth","token","csrf","parseOptions","secure","sameSite","httpOnly","multipart","preservePath","limits","parts","Infinity","fileSize","maxUploadSize","webSocketAdapter","WebSocketAdapter","initAdapter","useWebSocketAdapter"],"mappings":"AAAA;;;;CAIC;;;;+BAkBqBA;;;eAAAA;;;+DAhBI;+DACA;kEACJ;wBACqC;sBACpB;iCACgB;4BAER;8BACP;2BACd;uCACS;wBACM;iCACA;mCACX;kCACG;;;;;;AAE1B,eAAeA;IACpB,OAAO,GACP,MAAMC,iBAAiB,IAAIC,+BAAc,CAAC;QACxCC,QAAQ;QACRC,YAAYC,gCAAa,CAACC,MAAM,CAACF,UAAU;QAC3CG,qBAAqB;QACrBC,gBAAgB;QAChBC,WAAW,SAAS,SAAS;IAC/B;IACA,MAAMC,MAA8B,MAAMC,iBAAW,CAACC,MAAM,CAAyBC,oBAAS,EAAEZ,gBAAgB;QAC9Ga,YAAY;IACd;IAEA,oBAAoB,GACpB,MAAMC,kBAAkBd,eAAee,WAAW;IAElD,UAAU,GACVN,IAAIO,SAAS,CAACC,4BAAW,GAAG;QAAC;KAAQ,GAAGR,IAAIS,GAAG,CAACC,kBAAM;IAEtD,UAAU,GACV,6CAA6C;IAC7CV,IAAIW,aAAa,CAAC;QAAC;QAAmB;KAAW;IACjD,qBAAqB;IACrB,KAAK,MAAMC,UAAUC,OAAOC,MAAM,CAACC,yCAAkB,EAAG;QACtDV,gBAAgBW,aAAa,CAACJ,QAAQ;YAAEK,SAAS;QAAK;IACxD;IACA,oEAAoE;IACpEZ,gBAAgBa,oBAAoB,CAAC,KAAK;QAAEnB,WAAW;IAAE,GAAG,CAACoB,MAAsBC,UAAiCC,OAASA,KAAK;IAElI,2IAA2I;IAC3I,0HAA0H;IAC1H,4CAA4C;IAC5ChB,gBAAgBiB,OAAO,CAAC,aAAa,OAAOC,KAAKC;QAC/C,IAAI,AAACD,CAAAA,IAAIE,OAAO,CAAC,aAAa,IAAI,EAAC,EAAGC,OAAO,CAAC,cAAc,CAAC,KAAKH,IAAII,WAAW,CAACC,UAAU,CAACC,qBAAa,CAACC,iBAAS,CAACC,MAAM,CAAC,CAACC,KAAK,GAAG;YACnIT,IAAIE,OAAO,CAAC,eAAe,GAAG;QAChC;IACF;IAEA,gBAAgB,GAChBzB,IAAIiC,qBAAqB,CACvB,IAAIC,kCAAsB,IAC1B,IAAIC,kCAA0B,CAACnC,IAAIS,GAAG,CAAC2B,eAAS,GAAG;QACjDC,iBAAiB;YAAC;SAAI;IACxB;IAEF,cAAc,GACdrC,IAAIsC,cAAc,CAAC,IAAIC,sBAAc,CAAC;QAAEC,WAAW;QAAMC,WAAW;IAAK;IAEzE,UAAU,GACVzC,IAAI0C,eAAe,CAAC;QAAEC,MAAMC,4BAAW;QAAEC,0BAA0B;IAAK;IAExE,YAAY,GACZ,MAAM7C,IAAI8C,QAAQ,CAACC,eAAa,EAAE;QAAEC,uBAAuBC,IAAAA,qCAAuB,EAACtD,gCAAa,CAACuD,YAAY,CAACC,KAAK,CAACC,UAAU,CAACC,cAAc;IAAE;IAE/I,WAAW,GACX,2CAA2C;IAC3C,MAAMrD,IAAI8C,QAAQ,CAACQ,eAAa,EAAE;QAChCC,QAAQ5D,gCAAa,CAAC6D,IAAI,CAACC,KAAK,CAACC,IAAI,CAACH,MAAM;QAC5CI,cAAc;YACZC,QAAQ;YACRC,UAAUlE,gCAAa,CAAC6D,IAAI,CAACK,QAAQ;YACrCC,UAAU;QACZ;IACF;IAEA,UAAU,GACV,MAAM9D,IAAI8C,QAAQ,CAACiB,kBAAS,EAAE;QAC5BC,cAAc;QACdC,QAAQ;YAAEC,OAAOC;YAAUC,UAAUzE,gCAAa,CAACuD,YAAY,CAACC,KAAK,CAACkB,aAAa;QAAC;IACtF;IAEA,aAAa,GACb,IAAI,CAAC7D,4BAAW,EAAE;QAChB,MAAM8D,mBAAmB,IAAIC,kCAAgB,CAACvE;QAC9C,MAAMsE,iBAAiBE,WAAW;QAClCxE,IAAIyE,mBAAmB,CAACH;IAC1B;IAEA,OAAOtE;AACT"}
|
|
@@ -15,11 +15,15 @@ const _nodeprocess = /*#__PURE__*/ _interop_require_default(require("node:proces
|
|
|
15
15
|
const _appservice = require("./app.service");
|
|
16
16
|
const _configconstants = require("./configuration/config.constants");
|
|
17
17
|
const _configenvironment = require("./configuration/config.environment");
|
|
18
|
+
const _clusteradapter = require("@socket.io/cluster-adapter");
|
|
18
19
|
function _interop_require_default(obj) {
|
|
19
20
|
return obj && obj.__esModule ? obj : {
|
|
20
21
|
default: obj
|
|
21
22
|
};
|
|
22
23
|
}
|
|
24
|
+
jest.mock('@socket.io/cluster-adapter', ()=>({
|
|
25
|
+
setupPrimary: jest.fn()
|
|
26
|
+
}));
|
|
23
27
|
describe(_appservice.AppService.name, ()=>{
|
|
24
28
|
let appService;
|
|
25
29
|
beforeAll(async ()=>{
|
|
@@ -32,36 +36,59 @@ describe(_appservice.AppService.name, ()=>{
|
|
|
32
36
|
expect(appService).toBeDefined();
|
|
33
37
|
});
|
|
34
38
|
it('should clusterize', ()=>{
|
|
39
|
+
// --- MASTER, adapter='cluster' -> covers setupPrimary()
|
|
40
|
+
_configenvironment.configuration.websocket.adapter = 'cluster';
|
|
35
41
|
_configenvironment.configuration.server.restartOnFailure = true;
|
|
36
|
-
const
|
|
42
|
+
const bootstrap = jest.fn();
|
|
43
|
+
// IMPORTANT: do NOT call bootstrap() from fork mock
|
|
44
|
+
const fakeWorker = {
|
|
37
45
|
process: {
|
|
38
46
|
pid: 1
|
|
39
47
|
}
|
|
40
|
-
}
|
|
41
|
-
_nodecluster.default.fork = jest.fn(()=>
|
|
48
|
+
};
|
|
49
|
+
_nodecluster.default.fork = jest.fn(()=>fakeWorker);
|
|
42
50
|
const spyExit = jest.spyOn(_nodecluster.default, 'on');
|
|
43
|
-
|
|
44
|
-
expect(
|
|
45
|
-
|
|
46
|
-
|
|
51
|
+
// 1) master path (cluster.isPrimary true by default)
|
|
52
|
+
expect(()=>_appservice.AppService.clusterize(bootstrap)).not.toThrow();
|
|
53
|
+
// setupPrimary() must have run once (covers the “line 21” site)
|
|
54
|
+
expect(_clusteradapter.setupPrimary).toHaveBeenCalledTimes(1);
|
|
55
|
+
// fork called exactly workers times
|
|
56
|
+
expect(_nodecluster.default.fork.mock.calls.length).toBe(_configenvironment.configuration.server.workers);
|
|
57
|
+
// --- Test exit handler with ONLY ONE registered handler
|
|
58
|
+
// TRUE branch: restart twice -> fork called +2
|
|
59
|
+
const forkCallsAfterMaster = _nodecluster.default.fork.mock.calls.length;
|
|
47
60
|
_appservice.AppService.schedulerPID = 1;
|
|
48
61
|
_nodecluster.default.emit('exit', {
|
|
49
62
|
process: {
|
|
50
63
|
pid: 1
|
|
51
64
|
}
|
|
52
|
-
}, 1,
|
|
65
|
+
}, 1, 'SIGKILL');
|
|
53
66
|
_appservice.AppService.schedulerPID = 0;
|
|
54
67
|
_nodecluster.default.emit('exit', {
|
|
55
68
|
process: {
|
|
56
|
-
pid:
|
|
69
|
+
pid: 2
|
|
70
|
+
}
|
|
71
|
+
}, 1, 'SIGKILL');
|
|
72
|
+
expect(_nodecluster.default.fork.mock.calls.length).toBe(forkCallsAfterMaster + 2);
|
|
73
|
+
// FALSE branch: no restart -> fork unchanged
|
|
74
|
+
_configenvironment.configuration.server.restartOnFailure = false;
|
|
75
|
+
const forkCallsAfterTrue = _nodecluster.default.fork.mock.calls.length;
|
|
76
|
+
_nodecluster.default.emit('exit', {
|
|
77
|
+
process: {
|
|
78
|
+
pid: 3
|
|
57
79
|
}
|
|
58
|
-
}, 1,
|
|
59
|
-
expect(
|
|
60
|
-
|
|
80
|
+
}, 1, 'SIGKILL');
|
|
81
|
+
expect(_nodecluster.default.fork.mock.calls.length).toBe(forkCallsAfterTrue);
|
|
82
|
+
// --- MASTER again, adapter != 'cluster' -> covers the FALSE side of the adapter check
|
|
83
|
+
_configenvironment.configuration.websocket.adapter = null;
|
|
84
|
+
expect(()=>_appservice.AppService.clusterize(bootstrap)).not.toThrow();
|
|
85
|
+
// setupPrimary should NOT be called again
|
|
86
|
+
expect(_clusteradapter.setupPrimary).toHaveBeenCalledTimes(1);
|
|
87
|
+
// --- WORKER path (else branch): bootstrap should be called exactly once here
|
|
61
88
|
jest.replaceProperty(_nodecluster.default, 'isPrimary', false);
|
|
62
|
-
|
|
63
|
-
expect(()=>_appservice.AppService.clusterize(
|
|
64
|
-
expect(
|
|
89
|
+
bootstrap.mockClear(); // isolate bootstrap count for a worker branch
|
|
90
|
+
expect(()=>_appservice.AppService.clusterize(bootstrap)).not.toThrow();
|
|
91
|
+
expect(bootstrap).toHaveBeenCalledTimes(1);
|
|
65
92
|
spyExit.mockClear();
|
|
66
93
|
});
|
|
67
94
|
it(`should use ${_configconstants.ENVIRONMENT_PREFIX} environment variables to override the configuration`, ()=>{
|
|
@@ -82,12 +109,10 @@ describe(_appservice.AppService.name, ()=>{
|
|
|
82
109
|
expect(conf.logger.colorize).toBe(false);
|
|
83
110
|
expect(conf.applications.files.maxUploadSize).toBe(8888);
|
|
84
111
|
expect(conf.auth.token.access.secret).toBe('fooBAR8888');
|
|
85
|
-
//
|
|
112
|
+
// clean up secret file
|
|
86
113
|
_nodefs.default.promises.rm(tmpSecretFile, {
|
|
87
114
|
force: true
|
|
88
|
-
}).catch(
|
|
89
|
-
console.error(e);
|
|
90
|
-
});
|
|
115
|
+
}).catch(console.error);
|
|
91
116
|
});
|
|
92
117
|
});
|
|
93
118
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../backend/src/app.service.spec.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { Logger } from '@nestjs/common'\nimport cluster from 'node:cluster'\nimport fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { AppService } from './app.service'\nimport { ENVIRONMENT_PREFIX } from './configuration/config.constants'\nimport { configuration, exportConfiguration } from './configuration/config.environment'\n\ndescribe(AppService.name, () => {\n let appService: AppService\n\n beforeAll(async () => {\n appService = new AppService()\n Logger.overrideLogger(['fatal'])\n })\n\n it('should be defined', () => {\n expect(appService).toBeDefined()\n })\n\n it('should clusterize', () => {\n configuration.server.restartOnFailure = true\n const
|
|
1
|
+
{"version":3,"sources":["../../backend/src/app.service.spec.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { Logger } from '@nestjs/common'\nimport cluster from 'node:cluster'\nimport fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { AppService } from './app.service'\nimport { ENVIRONMENT_PREFIX } from './configuration/config.constants'\nimport { configuration, exportConfiguration } from './configuration/config.environment'\njest.mock('@socket.io/cluster-adapter', () => ({\n setupPrimary: jest.fn()\n}))\nimport { setupPrimary } from '@socket.io/cluster-adapter'\n\ndescribe(AppService.name, () => {\n let appService: AppService\n\n beforeAll(async () => {\n appService = new AppService()\n Logger.overrideLogger(['fatal'])\n })\n\n it('should be defined', () => {\n expect(appService).toBeDefined()\n })\n\n it('should clusterize', () => {\n // --- MASTER, adapter='cluster' -> covers setupPrimary()\n configuration.websocket.adapter = 'cluster'\n configuration.server.restartOnFailure = true\n\n const bootstrap = jest.fn()\n\n // IMPORTANT: do NOT call bootstrap() from fork mock\n const fakeWorker = { process: { pid: 1 } } as any\n cluster.fork = jest.fn(() => fakeWorker)\n\n const spyExit = jest.spyOn(cluster, 'on')\n\n // 1) master path (cluster.isPrimary true by default)\n expect(() => AppService.clusterize(bootstrap)).not.toThrow()\n\n // setupPrimary() must have run once (covers the “line 21” site)\n expect(setupPrimary).toHaveBeenCalledTimes(1)\n\n // fork called exactly workers times\n expect((cluster.fork as jest.Mock).mock.calls.length).toBe(configuration.server.workers)\n\n // --- Test exit handler with ONLY ONE registered handler\n // TRUE branch: restart twice -> fork called +2\n const forkCallsAfterMaster = (cluster.fork as jest.Mock).mock.calls.length\n AppService.schedulerPID = 1\n cluster.emit('exit', { process: { pid: 1 } } as any, 1 as any, 'SIGKILL' as any)\n AppService.schedulerPID = 0\n cluster.emit('exit', { process: { pid: 2 } } as any, 1 as any, 'SIGKILL' as any)\n expect((cluster.fork as jest.Mock).mock.calls.length).toBe(forkCallsAfterMaster + 2)\n\n // FALSE branch: no restart -> fork unchanged\n configuration.server.restartOnFailure = false\n const forkCallsAfterTrue = (cluster.fork as jest.Mock).mock.calls.length\n cluster.emit('exit', { process: { pid: 3 } } as any, 1 as any, 'SIGKILL' as any)\n expect((cluster.fork as jest.Mock).mock.calls.length).toBe(forkCallsAfterTrue)\n\n // --- MASTER again, adapter != 'cluster' -> covers the FALSE side of the adapter check\n configuration.websocket.adapter = null\n expect(() => AppService.clusterize(bootstrap)).not.toThrow()\n // setupPrimary should NOT be called again\n expect(setupPrimary).toHaveBeenCalledTimes(1)\n\n // --- WORKER path (else branch): bootstrap should be called exactly once here\n jest.replaceProperty(cluster, 'isPrimary', false)\n bootstrap.mockClear() // isolate bootstrap count for a worker branch\n expect(() => AppService.clusterize(bootstrap)).not.toThrow()\n expect(bootstrap).toHaveBeenCalledTimes(1)\n\n spyExit.mockClear()\n })\n\n it(`should use ${ENVIRONMENT_PREFIX} environment variables to override the configuration`, () => {\n let conf = exportConfiguration()\n expect(conf.logger.stdout).toBe(true)\n expect(conf.logger.colorize).toBe(true)\n const tmpSecretFile = path.join(os.tmpdir(), 'secret')\n fs.writeFileSync(tmpSecretFile, 'fooBAR8888')\n process.env[`${ENVIRONMENT_PREFIX}APPLICATIONS_FILES_ONLYOFFICE_SECRET`] = 'fooBAR'\n process.env[`${ENVIRONMENT_PREFIX}LOGGER_STDOUT`] = 'false'\n process.env[`${ENVIRONMENT_PREFIX}LOGGER_COLORIZE`] = '\"false\"'\n process.env[`${ENVIRONMENT_PREFIX}APPLICATIONS_FILES_MAXUPLOADSIZE`] = '8888'\n // docker compose secret file\n process.env[`${ENVIRONMENT_PREFIX}AUTH_TOKEN_ACCESS_SECRET_FILE`] = tmpSecretFile\n conf = exportConfiguration(true)\n expect(conf.applications.files.onlyoffice.secret).toBe('fooBAR')\n expect(conf.logger.stdout).toBe(false)\n expect(conf.logger.colorize).toBe(false)\n expect(conf.applications.files.maxUploadSize).toBe(8888)\n expect(conf.auth.token.access.secret).toBe('fooBAR8888')\n // clean up secret file\n fs.promises.rm(tmpSecretFile, { force: true }).catch(console.error)\n })\n})\n"],"names":["jest","mock","setupPrimary","fn","describe","AppService","name","appService","beforeAll","Logger","overrideLogger","it","expect","toBeDefined","configuration","websocket","adapter","server","restartOnFailure","bootstrap","fakeWorker","process","pid","cluster","fork","spyExit","spyOn","clusterize","not","toThrow","toHaveBeenCalledTimes","calls","length","toBe","workers","forkCallsAfterMaster","schedulerPID","emit","forkCallsAfterTrue","replaceProperty","mockClear","ENVIRONMENT_PREFIX","conf","exportConfiguration","logger","stdout","colorize","tmpSecretFile","path","join","os","tmpdir","fs","writeFileSync","env","applications","files","onlyoffice","secret","maxUploadSize","auth","token","access","promises","rm","force","catch","console","error"],"mappings":"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"}
|
|
@@ -16,9 +16,6 @@ _export(exports, {
|
|
|
16
16
|
get COMPRESSION_EXTENSION () {
|
|
17
17
|
return COMPRESSION_EXTENSION;
|
|
18
18
|
},
|
|
19
|
-
get DEFAULT_FILTERS () {
|
|
20
|
-
return DEFAULT_FILTERS;
|
|
21
|
-
},
|
|
22
19
|
get DEFAULT_HIGH_WATER_MARK () {
|
|
23
20
|
return DEFAULT_HIGH_WATER_MARK;
|
|
24
21
|
},
|
|
@@ -31,26 +28,6 @@ _export(exports, {
|
|
|
31
28
|
});
|
|
32
29
|
const DEFAULT_HIGH_WATER_MARK = 1024 * 1024;
|
|
33
30
|
const DEFAULT_MIME_TYPE = 'application/octet-stream';
|
|
34
|
-
const DEFAULT_FILTERS = new Set([
|
|
35
|
-
'.DS_Store',
|
|
36
|
-
'.swp',
|
|
37
|
-
'.AppleDouble',
|
|
38
|
-
'.AppleDesktop',
|
|
39
|
-
'Thumbs.db',
|
|
40
|
-
'.Spotlight-V100',
|
|
41
|
-
'.DocumentRevisions-V100',
|
|
42
|
-
'.fseventsd',
|
|
43
|
-
'.MobileBackups',
|
|
44
|
-
'Icon?',
|
|
45
|
-
'__MACOSX',
|
|
46
|
-
'.thumbnails',
|
|
47
|
-
'.DAV',
|
|
48
|
-
'.desktop',
|
|
49
|
-
'desktop.ini',
|
|
50
|
-
'.TemporaryItems',
|
|
51
|
-
'.localized',
|
|
52
|
-
'__pycache__'
|
|
53
|
-
]);
|
|
54
31
|
const EXTRA_MIMES_TYPE = new Map([
|
|
55
32
|
[
|
|
56
33
|
'.ts',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/files/constants/files.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 DEFAULT_HIGH_WATER_MARK = 1024 * 1024\nexport const DEFAULT_MIME_TYPE = 'application/octet-stream'\nexport const
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/files/constants/files.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 DEFAULT_HIGH_WATER_MARK = 1024 * 1024\nexport const DEFAULT_MIME_TYPE = 'application/octet-stream'\nexport const EXTRA_MIMES_TYPE = new Map([\n ['.ts', 'text-typescript'],\n ['.py', 'text-x-python'],\n ['.tgz', 'application-gzip'],\n ['.gz', 'application-gzip'],\n ['.gzip', 'application-gzip']\n])\nexport const COMPRESSION_EXTENSION = new Map([\n ['.zip', 'zip'],\n ['.gzip', 'gzip'],\n ['.tgz', 'tgz'],\n ['.gz', 'tgz'],\n ['.tar.gz', 'tgz'],\n ['.tar', 'tar']\n])\n"],"names":["COMPRESSION_EXTENSION","DEFAULT_HIGH_WATER_MARK","DEFAULT_MIME_TYPE","EXTRA_MIMES_TYPE","Map"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAWYA;eAAAA;;QATAC;eAAAA;;QACAC;eAAAA;;QACAC;eAAAA;;;AAFN,MAAMF,0BAA0B,OAAO;AACvC,MAAMC,oBAAoB;AAC1B,MAAMC,mBAAmB,IAAIC,IAAI;IACtC;QAAC;QAAO;KAAkB;IAC1B;QAAC;QAAO;KAAgB;IACxB;QAAC;QAAQ;KAAmB;IAC5B;QAAC;QAAO;KAAmB;IAC3B;QAAC;QAAS;KAAmB;CAC9B;AACM,MAAMJ,wBAAwB,IAAII,IAAI;IAC3C;QAAC;QAAQ;KAAM;IACf;QAAC;QAAS;KAAO;IACjB;QAAC;QAAQ;KAAM;IACf;QAAC;QAAO;KAAM;IACd;QAAC;QAAW;KAAM;IAClB;QAAC;QAAQ;KAAM;CAChB"}
|
|
@@ -147,6 +147,10 @@ const ONLY_OFFICE_EXTENSIONS = {
|
|
|
147
147
|
'xml',
|
|
148
148
|
'word'
|
|
149
149
|
],
|
|
150
|
+
[
|
|
151
|
+
'md',
|
|
152
|
+
'word'
|
|
153
|
+
],
|
|
150
154
|
// CELL
|
|
151
155
|
[
|
|
152
156
|
'csv',
|
|
@@ -378,6 +382,10 @@ const ONLY_OFFICE_EXTENSIONS = {
|
|
|
378
382
|
'txt',
|
|
379
383
|
'word'
|
|
380
384
|
],
|
|
385
|
+
[
|
|
386
|
+
'md',
|
|
387
|
+
'word'
|
|
388
|
+
],
|
|
381
389
|
// CELL
|
|
382
390
|
[
|
|
383
391
|
'xlsb',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/files/constants/only-office.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 ONLY_OFFICE_INTERNAL_URI = '/onlyoffice' // used by nginx as proxy\nexport const ONLY_OFFICE_CONTEXT = 'OnlyOfficeEnvironment'\nexport const ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME = 'token' as const\n\nexport const ONLY_OFFICE_EXTENSIONS = {\n VIEWABLE: new Map([\n // WORD\n ['doc', 'word'],\n ['docm', 'word'],\n ['docx', 'word'],\n ['dot', 'word'],\n ['dotm', 'word'],\n ['dotx', 'word'],\n ['epub', 'word'],\n ['fb2', 'word'],\n ['fodt', 'word'],\n ['gdoc', 'word'],\n ['htm', 'word'],\n ['html', 'word'],\n ['hwp', 'word'],\n ['hwpx', 'word'],\n ['md', 'word'],\n ['mht', 'word'],\n ['mhtml', 'word'],\n ['odt', 'word'],\n ['ott', 'word'],\n ['pages', 'word'],\n ['rtf', 'word'],\n ['stw', 'word'],\n ['sxw', 'word'],\n ['txt', 'word'],\n ['wps', 'word'],\n ['wpt', 'word'],\n ['xml', 'word'],\n\n // CELL\n ['csv', 'cell'],\n ['et', 'cell'],\n ['ett', 'cell'],\n ['fods', 'cell'],\n ['gsheet', 'cell'],\n ['numbers', 'cell'],\n ['ods', 'cell'],\n ['ots', 'cell'],\n ['sxc', 'cell'],\n ['xls', 'cell'],\n ['xlsm', 'cell'],\n ['xlsx', 'cell'],\n ['xlt', 'cell'],\n ['xltm', 'cell'],\n ['xltx', 'cell'],\n\n // SLIDE\n ['dps', 'slide'],\n ['dpt', 'slide'],\n ['fodp', 'slide'],\n ['gslide', 'slide'],\n ['key', 'slide'],\n ['odg', 'slide'],\n ['odp', 'slide'],\n ['otp', 'slide'],\n ['pot', 'slide'],\n ['potm', 'slide'],\n ['potx', 'slide'],\n ['pps', 'slide'],\n ['ppsm', 'slide'],\n ['ppsx', 'slide'],\n ['ppt', 'slide'],\n ['pptm', 'slide'],\n ['pptx', 'slide'],\n ['sxi', 'slide'],\n\n // PDF\n ['djvu', 'pdf'],\n ['docxf', 'pdf'],\n ['oform', 'pdf'],\n ['oxps', 'pdf'],\n ['pdf', 'pdf'],\n ['xps', 'pdf'],\n\n // DIAGRAM\n ['vsdm', 'diagram'],\n ['vsdx', 'diagram'],\n ['vssm', 'diagram'],\n ['vssx', 'diagram'],\n ['vstm', 'diagram'],\n ['vstx', 'diagram']\n ]),\n\n EDITABLE: new Map([\n // WORD\n ['docm', 'word'],\n ['docx', 'word'],\n ['dotm', 'word'],\n ['dotx', 'word'],\n ['epub', 'word'],\n ['fb2', 'word'],\n ['html', 'word'],\n ['odt', 'word'],\n ['ott', 'word'],\n ['rtf', 'word'],\n ['txt', 'word'],\n\n // CELL\n ['xlsb', 'cell'],\n ['xlsm', 'cell'],\n ['xlsx', 'cell'],\n ['xltm', 'cell'],\n ['xltx', 'cell'],\n ['csv', 'cell'],\n ['ods', 'cell'],\n ['ots', 'cell'],\n\n // SLIDE\n ['potm', 'slide'],\n ['potx', 'slide'],\n ['ppsm', 'slide'],\n ['ppsx', 'slide'],\n ['pptm', 'slide'],\n ['pptx', 'slide'],\n ['odp', 'slide'],\n ['otp', 'slide'],\n\n // PDF\n ['pdf', 'pdf']\n ])\n}\n\nexport const ONLY_OFFICE_CONVERT_EXTENSIONS = {\n ALLOW_AUTO: new Set(['doc', 'xls', 'ppt']),\n FROM: new Set([\n 'doc',\n 'docm',\n 'docx',\n 'docxf',\n 'dotx',\n 'epub',\n 'fb2',\n 'html',\n 'mhtml',\n 'odt',\n 'ott',\n 'pdf',\n 'rtf',\n 'stw',\n 'sxw',\n 'txt',\n 'wps',\n 'wpt',\n 'xps'\n ]),\n TO: new Set(['docx', 'docxf', 'dotx', 'epub', 'fb2', 'html', 'jpg', 'odt', 'ott', 'pdf', 'png', 'rtf', 'txt'])\n}\n\nexport const ONLY_OFFICE_CONVERT_ERROR = new Map([\n [-9, 'error conversion output format'],\n [-8, 'error document VKey'],\n [-7, 'error document request'],\n [-6, 'error database'],\n [-5, 'incorrect password'],\n [-4, 'download error'],\n [-3, 'convert error'],\n [-2, 'convert error timeout'],\n [-1, 'convert unknown']\n])\n"],"names":["ONLY_OFFICE_CONTEXT","ONLY_OFFICE_CONVERT_ERROR","ONLY_OFFICE_CONVERT_EXTENSIONS","ONLY_OFFICE_EXTENSIONS","ONLY_OFFICE_INTERNAL_URI","ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME","VIEWABLE","Map","EDITABLE","ALLOW_AUTO","Set","FROM","TO"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAGYA;eAAAA;;
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/files/constants/only-office.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 ONLY_OFFICE_INTERNAL_URI = '/onlyoffice' // used by nginx as proxy\nexport const ONLY_OFFICE_CONTEXT = 'OnlyOfficeEnvironment'\nexport const ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME = 'token' as const\n\nexport const ONLY_OFFICE_EXTENSIONS = {\n VIEWABLE: new Map([\n // WORD\n ['doc', 'word'],\n ['docm', 'word'],\n ['docx', 'word'],\n ['dot', 'word'],\n ['dotm', 'word'],\n ['dotx', 'word'],\n ['epub', 'word'],\n ['fb2', 'word'],\n ['fodt', 'word'],\n ['gdoc', 'word'],\n ['htm', 'word'],\n ['html', 'word'],\n ['hwp', 'word'],\n ['hwpx', 'word'],\n ['md', 'word'],\n ['mht', 'word'],\n ['mhtml', 'word'],\n ['odt', 'word'],\n ['ott', 'word'],\n ['pages', 'word'],\n ['rtf', 'word'],\n ['stw', 'word'],\n ['sxw', 'word'],\n ['txt', 'word'],\n ['wps', 'word'],\n ['wpt', 'word'],\n ['xml', 'word'],\n ['md', 'word'],\n\n // CELL\n ['csv', 'cell'],\n ['et', 'cell'],\n ['ett', 'cell'],\n ['fods', 'cell'],\n ['gsheet', 'cell'],\n ['numbers', 'cell'],\n ['ods', 'cell'],\n ['ots', 'cell'],\n ['sxc', 'cell'],\n ['xls', 'cell'],\n ['xlsm', 'cell'],\n ['xlsx', 'cell'],\n ['xlt', 'cell'],\n ['xltm', 'cell'],\n ['xltx', 'cell'],\n\n // SLIDE\n ['dps', 'slide'],\n ['dpt', 'slide'],\n ['fodp', 'slide'],\n ['gslide', 'slide'],\n ['key', 'slide'],\n ['odg', 'slide'],\n ['odp', 'slide'],\n ['otp', 'slide'],\n ['pot', 'slide'],\n ['potm', 'slide'],\n ['potx', 'slide'],\n ['pps', 'slide'],\n ['ppsm', 'slide'],\n ['ppsx', 'slide'],\n ['ppt', 'slide'],\n ['pptm', 'slide'],\n ['pptx', 'slide'],\n ['sxi', 'slide'],\n\n // PDF\n ['djvu', 'pdf'],\n ['docxf', 'pdf'],\n ['oform', 'pdf'],\n ['oxps', 'pdf'],\n ['pdf', 'pdf'],\n ['xps', 'pdf'],\n\n // DIAGRAM\n ['vsdm', 'diagram'],\n ['vsdx', 'diagram'],\n ['vssm', 'diagram'],\n ['vssx', 'diagram'],\n ['vstm', 'diagram'],\n ['vstx', 'diagram']\n ]),\n\n EDITABLE: new Map([\n // WORD\n ['docm', 'word'],\n ['docx', 'word'],\n ['dotm', 'word'],\n ['dotx', 'word'],\n ['epub', 'word'],\n ['fb2', 'word'],\n ['html', 'word'],\n ['odt', 'word'],\n ['ott', 'word'],\n ['rtf', 'word'],\n ['txt', 'word'],\n ['md', 'word'],\n\n // CELL\n ['xlsb', 'cell'],\n ['xlsm', 'cell'],\n ['xlsx', 'cell'],\n ['xltm', 'cell'],\n ['xltx', 'cell'],\n ['csv', 'cell'],\n ['ods', 'cell'],\n ['ots', 'cell'],\n\n // SLIDE\n ['potm', 'slide'],\n ['potx', 'slide'],\n ['ppsm', 'slide'],\n ['ppsx', 'slide'],\n ['pptm', 'slide'],\n ['pptx', 'slide'],\n ['odp', 'slide'],\n ['otp', 'slide'],\n\n // PDF\n ['pdf', 'pdf']\n ])\n}\n\nexport const ONLY_OFFICE_CONVERT_EXTENSIONS = {\n ALLOW_AUTO: new Set(['doc', 'xls', 'ppt']),\n FROM: new Set([\n 'doc',\n 'docm',\n 'docx',\n 'docxf',\n 'dotx',\n 'epub',\n 'fb2',\n 'html',\n 'mhtml',\n 'odt',\n 'ott',\n 'pdf',\n 'rtf',\n 'stw',\n 'sxw',\n 'txt',\n 'wps',\n 'wpt',\n 'xps'\n ]),\n TO: new Set(['docx', 'docxf', 'dotx', 'epub', 'fb2', 'html', 'jpg', 'odt', 'ott', 'pdf', 'png', 'rtf', 'txt'])\n}\n\nexport const ONLY_OFFICE_CONVERT_ERROR = new Map([\n [-9, 'error conversion output format'],\n [-8, 'error document VKey'],\n [-7, 'error document request'],\n [-6, 'error database'],\n [-5, 'incorrect password'],\n [-4, 'download error'],\n [-3, 'convert error'],\n [-2, 'convert error timeout'],\n [-1, 'convert unknown']\n])\n"],"names":["ONLY_OFFICE_CONTEXT","ONLY_OFFICE_CONVERT_ERROR","ONLY_OFFICE_CONVERT_EXTENSIONS","ONLY_OFFICE_EXTENSIONS","ONLY_OFFICE_INTERNAL_URI","ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME","VIEWABLE","Map","EDITABLE","ALLOW_AUTO","Set","FROM","TO"],"mappings":"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"}
|
|
@@ -59,6 +59,7 @@ _ts_decorate([
|
|
|
59
59
|
let FilesConfig = class FilesConfig {
|
|
60
60
|
constructor(){
|
|
61
61
|
this.maxUploadSize = 5368709120; // 5 GB
|
|
62
|
+
this.showHiddenFiles = false;
|
|
62
63
|
this.onlyoffice = new FilesOnlyOfficeConfig();
|
|
63
64
|
}
|
|
64
65
|
};
|
|
@@ -86,6 +87,10 @@ _ts_decorate([
|
|
|
86
87
|
(0, _classvalidator.IsInt)(),
|
|
87
88
|
_ts_metadata("design:type", Number)
|
|
88
89
|
], FilesConfig.prototype, "maxUploadSize", void 0);
|
|
90
|
+
_ts_decorate([
|
|
91
|
+
(0, _classvalidator.IsBoolean)(),
|
|
92
|
+
_ts_metadata("design:type", Boolean)
|
|
93
|
+
], FilesConfig.prototype, "showHiddenFiles", void 0);
|
|
89
94
|
_ts_decorate([
|
|
90
95
|
(0, _classvalidator.IsNotEmptyObject)(),
|
|
91
96
|
(0, _classvalidator.ValidateNested)(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../backend/src/applications/files/files.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 { Type } from 'class-transformer'\nimport { IsBoolean, IsInt, IsNotEmpty, IsNotEmptyObject, IsOptional, IsString, ValidateIf, ValidateNested } from 'class-validator'\n\nexport class FilesOnlyOfficeConfig {\n @IsBoolean()\n enabled = false\n\n @IsOptional()\n @IsString()\n externalServer: string = null\n\n @ValidateIf((o: FilesOnlyOfficeConfig) => o.enabled)\n @IsString()\n @IsNotEmpty()\n secret: string\n\n @IsBoolean()\n verifySSL: boolean = false\n}\n\nexport class FilesConfig {\n @IsNotEmpty()\n @IsString()\n dataPath: string\n\n @IsNotEmpty()\n @IsString()\n usersPath: string\n\n @IsNotEmpty()\n @IsString()\n spacesPath: string\n\n @IsNotEmpty()\n @IsString()\n tmpPath: string\n\n @IsInt()\n maxUploadSize: number = 5368709120 // 5 GB\n\n @IsNotEmptyObject()\n @ValidateNested()\n @Type(() => FilesOnlyOfficeConfig)\n onlyoffice: FilesOnlyOfficeConfig = new FilesOnlyOfficeConfig()\n}\n"],"names":["FilesConfig","FilesOnlyOfficeConfig","enabled","externalServer","verifySSL","o","maxUploadSize","onlyoffice"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAsBYA;eAAAA;;QAjBAC;eAAAA;;;kCAHQ;gCAC4F;;;;;;;;;;AAE1G,IAAA,AAAMA,wBAAN,MAAMA;;aAEXC,UAAU;aAIVC,iBAAyB;aAQzBC,YAAqB;;AACvB;;;;;;;;;;qCAPeC,IAA6BA,EAAEH,OAAO;;;;;;;;;AAS9C,IAAA,AAAMF,cAAN,MAAMA;;aAkBXM,gBAAwB,YAAW,OAAO;
|
|
1
|
+
{"version":3,"sources":["../../../../backend/src/applications/files/files.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 { Type } from 'class-transformer'\nimport { IsBoolean, IsInt, IsNotEmpty, IsNotEmptyObject, IsOptional, IsString, ValidateIf, ValidateNested } from 'class-validator'\n\nexport class FilesOnlyOfficeConfig {\n @IsBoolean()\n enabled = false\n\n @IsOptional()\n @IsString()\n externalServer: string = null\n\n @ValidateIf((o: FilesOnlyOfficeConfig) => o.enabled)\n @IsString()\n @IsNotEmpty()\n secret: string\n\n @IsBoolean()\n verifySSL: boolean = false\n}\n\nexport class FilesConfig {\n @IsNotEmpty()\n @IsString()\n dataPath: string\n\n @IsNotEmpty()\n @IsString()\n usersPath: string\n\n @IsNotEmpty()\n @IsString()\n spacesPath: string\n\n @IsNotEmpty()\n @IsString()\n tmpPath: string\n\n @IsInt()\n maxUploadSize: number = 5368709120 // 5 GB\n\n @IsBoolean()\n showHiddenFiles: boolean = false\n\n @IsNotEmptyObject()\n @ValidateNested()\n @Type(() => FilesOnlyOfficeConfig)\n onlyoffice: FilesOnlyOfficeConfig = new FilesOnlyOfficeConfig()\n}\n"],"names":["FilesConfig","FilesOnlyOfficeConfig","enabled","externalServer","verifySSL","o","maxUploadSize","showHiddenFiles","onlyoffice"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAsBYA;eAAAA;;QAjBAC;eAAAA;;;kCAHQ;gCAC4F;;;;;;;;;;AAE1G,IAAA,AAAMA,wBAAN,MAAMA;;aAEXC,UAAU;aAIVC,iBAAyB;aAQzBC,YAAqB;;AACvB;;;;;;;;;;qCAPeC,IAA6BA,EAAEH,OAAO;;;;;;;;;AAS9C,IAAA,AAAMF,cAAN,MAAMA;;aAkBXM,gBAAwB,YAAW,OAAO;aAG1CC,kBAA2B;aAK3BC,aAAoC,IAAIP;;AAC1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCAFcA"}
|
|
@@ -30,7 +30,6 @@ function _ts_metadata(k, v) {
|
|
|
30
30
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
31
31
|
}
|
|
32
32
|
let FilesOnlyOfficeStrategy = class FilesOnlyOfficeStrategy extends (0, _passport.PassportStrategy)(_passportjwt.Strategy, 'filesOnlyOfficeToken') {
|
|
33
|
-
// not declared properly: https://github.com/nestjs/passport/issues/929
|
|
34
33
|
validate(jwtPayload) {
|
|
35
34
|
this.logger.assign({
|
|
36
35
|
user: jwtPayload.identity.login
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/files/guards/files-only-office.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 { PassportStrategy } from '@nestjs/passport'\nimport { PinoLogger } from 'nestjs-pino'\nimport { ExtractJwt, Strategy } from 'passport-jwt'\nimport { AuthTokenAccessStrategy } from '../../../authentication/guards/auth-token-access.strategy'\nimport { JwtPayload } from '../../../authentication/interfaces/jwt-payload.interface'\nimport { configuration } from '../../../configuration/config.environment'\nimport { UserModel } from '../../users/models/user.model'\nimport { ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME } from '../constants/only-office'\n\n@Injectable()\nexport class FilesOnlyOfficeStrategy extends PassportStrategy(Strategy, 'filesOnlyOfficeToken') {\n constructor(private readonly logger: PinoLogger) {\n super({\n jwtFromRequest: ExtractJwt.fromExtractors([\n AuthTokenAccessStrategy.extractJWTFromCookie,\n ExtractJwt.fromUrlQueryParameter(ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME)\n ]),\n secretOrKey: configuration.auth.token.access.secret,\n ignoreExpiration: false,\n passReqToCallback: false\n })\n }\n\n
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/files/guards/files-only-office.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 { PinoLogger } from 'nestjs-pino'\nimport { ExtractJwt, Strategy } from 'passport-jwt'\nimport { AuthTokenAccessStrategy } from '../../../authentication/guards/auth-token-access.strategy'\nimport { JwtPayload } from '../../../authentication/interfaces/jwt-payload.interface'\nimport { configuration } from '../../../configuration/config.environment'\nimport { UserModel } from '../../users/models/user.model'\nimport { ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME } from '../constants/only-office'\n\n@Injectable()\nexport class FilesOnlyOfficeStrategy extends PassportStrategy(Strategy, 'filesOnlyOfficeToken') implements AbstractStrategy {\n constructor(private readonly logger: PinoLogger) {\n super({\n jwtFromRequest: ExtractJwt.fromExtractors([\n AuthTokenAccessStrategy.extractJWTFromCookie,\n ExtractJwt.fromUrlQueryParameter(ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME)\n ]),\n secretOrKey: configuration.auth.token.access.secret,\n ignoreExpiration: false,\n passReqToCallback: false\n })\n }\n\n validate(jwtPayload: JwtPayload): UserModel {\n this.logger.assign({ user: jwtPayload.identity.login })\n return new UserModel(jwtPayload.identity)\n }\n}\n"],"names":["FilesOnlyOfficeStrategy","PassportStrategy","Strategy","validate","jwtPayload","logger","assign","user","identity","login","UserModel","jwtFromRequest","ExtractJwt","fromExtractors","AuthTokenAccessStrategy","extractJWTFromCookie","fromUrlQueryParameter","ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME","secretOrKey","configuration","auth","token","access","secret","ignoreExpiration","passReqToCallback"],"mappings":"AAAA;;;;CAIC;;;;+BAaYA;;;eAAAA;;;wBAXc;0BACwB;4BACxB;6BACU;yCACG;mCAEV;2BACJ;4BACyB;;;;;;;;;;AAG5C,IAAA,AAAMA,0BAAN,MAAMA,gCAAgCC,IAAAA,0BAAgB,EAACC,qBAAQ,EAAE;IAatEC,SAASC,UAAsB,EAAa;QAC1C,IAAI,CAACC,MAAM,CAACC,MAAM,CAAC;YAAEC,MAAMH,WAAWI,QAAQ,CAACC,KAAK;QAAC;QACrD,OAAO,IAAIC,oBAAS,CAACN,WAAWI,QAAQ;IAC1C;IAfA,YAAY,AAAiBH,MAAkB,CAAE;QAC/C,KAAK,CAAC;YACJM,gBAAgBC,uBAAU,CAACC,cAAc,CAAC;gBACxCC,gDAAuB,CAACC,oBAAoB;gBAC5CH,uBAAU,CAACI,qBAAqB,CAACC,8CAAkC;aACpE;YACDC,aAAaC,gCAAa,CAACC,IAAI,CAACC,KAAK,CAACC,MAAM,CAACC,MAAM;YACnDC,kBAAkB;YAClBC,mBAAmB;QACrB,SAT2BpB,SAAAA;IAU7B;AAMF"}
|