Skip to content

Commit dabeff6

Browse files
committed
feat(files): collabora online integration
1 parent e0053ae commit dabeff6

File tree

76 files changed

+1521
-553
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1521
-553
lines changed

backend/src/app.bootstrap.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,12 @@ export async function appBootstrap(): Promise<NestFastifyApplication> {
7777
app.useStaticAssets({ root: STATIC_PATH, prefixAvoidTrailingSlash: true })
7878

7979
/* SECURITY */
80-
await app.register(fastifyHelmet, { contentSecurityPolicy: CONTENT_SECURITY_POLICY(configuration.applications.files.onlyoffice.externalServer) })
80+
await app.register(fastifyHelmet, {
81+
contentSecurityPolicy: CONTENT_SECURITY_POLICY(
82+
configuration.applications.files.onlyoffice.externalServer,
83+
configuration.applications.files.collabora.externalServer
84+
)
85+
})
8186

8287
/* COOKIES */
8388
// we use csrf secret to unsign csrf cookie

backend/src/app.constants.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import { loadVersion } from './app.functions'
88

99
export const VERSION = loadVersion()
1010
export const USER_AGENT = `sync-in-server/${VERSION}`
11-
export const CONTENT_SECURITY_POLICY = (onlyOfficeServer: string) => ({
11+
export const CONTENT_SECURITY_POLICY = (onlyOfficeServer: string, collaboraServer: string) => ({
1212
useDefaults: false,
1313
directives: {
14-
defaultSrc: ["'self'", onlyOfficeServer || ''],
14+
defaultSrc: ["'self'", onlyOfficeServer || '', collaboraServer || ''],
1515
scriptSrc: ["'self'", "'unsafe-inline'", onlyOfficeServer || ''],
1616
styleSrc: ["'self'", "'unsafe-inline'"],
1717
imgSrc: ["'self'", 'data:'],

backend/src/applications/files/constants/cache.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,3 @@ export const CACHE_LOCK_PREFIX = 'flock' as const
1212
export const CACHE_LOCK_DEFAULT_TTL = 28800 as const // 8 hours in seconds
1313
export const CACHE_LOCK_FILE_TTL = 3600 as const
1414
// cache only office = `office|${fileId}` => docKey
15-
export const CACHE_ONLY_OFFICE = 'foffice' as const

backend/src/applications/files/constants/files.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* See the LICENSE file for licensing details
55
*/
66

7+
export const DEFAULT_CHECKSUM_ALGORITHM = 'sha512-256'
78
export const DEFAULT_HIGH_WATER_MARK = 1024 * 1024
89
export const DEFAULT_MIME_TYPE = 'application/octet-stream'
910
export const EXTRA_MIMES_TYPE = new Map([

backend/src/applications/files/constants/operations.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,5 @@ export enum FILE_MODE {
2525
VIEW = 'view',
2626
EDIT = 'edit'
2727
}
28+
29+
export const FORCE_AS_FILE_OWNER = 'forceAsFileOwner' as const

backend/src/applications/files/constants/routes.ts

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,13 @@ import { FILE_OPERATION } from './operations'
99

1010
export const FILES_ROUTE = {
1111
BASE: SPACES_ROUTE.BASE,
12+
SETTINGS: 'settings',
1213
OPERATION: 'operation',
1314
TASK_OPERATION: 'task/operation',
1415
TASKS: 'tasks',
1516
TASKS_DOWNLOAD: 'download',
1617
RECENTS: 'recents',
17-
SEARCH: 'search',
18-
ONLY_OFFICE: 'onlyoffice',
19-
ONLY_OFFICE_SETTINGS: 'settings',
20-
ONLY_OFFICE_DOCUMENT: 'document',
21-
ONLY_OFFICE_CALLBACK: 'callback',
22-
ONLY_OFFICE_STATUS: 'status'
18+
SEARCH: 'search'
2319
} as const
2420

2521
export const API_FILES_OPERATION = `${FILES_ROUTE.BASE}/${FILES_ROUTE.OPERATION}`
@@ -32,10 +28,6 @@ export const API_FILES_TASK_OPERATION_COMPRESS = `${API_FILES_TASK_OPERATION}/${
3228
export const API_FILES_TASK_OPERATION_DECOMPRESS = `${API_FILES_TASK_OPERATION}/${FILE_OPERATION.DECOMPRESS}`
3329
export const API_FILES_TASKS = `${FILES_ROUTE.BASE}/${FILES_ROUTE.TASKS}`
3430
export const API_FILES_TASKS_DOWNLOAD = `${FILES_ROUTE.BASE}/${FILES_ROUTE.TASKS}/${FILES_ROUTE.TASKS_DOWNLOAD}`
31+
export const API_FILES_SETTINGS = `${FILES_ROUTE.BASE}/${FILES_ROUTE.SETTINGS}`
3532
export const API_FILES_RECENTS = `${FILES_ROUTE.BASE}/${FILES_ROUTE.RECENTS}`
3633
export const API_FILES_SEARCH = `${FILES_ROUTE.BASE}/${FILES_ROUTE.SEARCH}`
37-
export const API_FILES_ONLY_OFFICE = `${FILES_ROUTE.BASE}/${FILES_ROUTE.ONLY_OFFICE}`
38-
export const API_FILES_ONLY_OFFICE_SETTINGS = `${API_FILES_ONLY_OFFICE}/${FILES_ROUTE.ONLY_OFFICE_SETTINGS}`
39-
export const API_FILES_ONLY_OFFICE_DOCUMENT = `${API_FILES_ONLY_OFFICE}/${FILES_ROUTE.ONLY_OFFICE_DOCUMENT}`
40-
export const API_FILES_ONLY_OFFICE_CALLBACK = `${API_FILES_ONLY_OFFICE}/${FILES_ROUTE.ONLY_OFFICE_CALLBACK}`
41-
export const API_FILES_ONLY_OFFICE_STATUS = `${API_FILES_ONLY_OFFICE}/${FILES_ROUTE.ONLY_OFFICE_STATUS}`

backend/src/applications/files/files-only-office.controller.ts

Lines changed: 0 additions & 58 deletions
This file was deleted.

backend/src/applications/files/files.config.ts

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,9 @@
55
*/
66

77
import { Type } from 'class-transformer'
8-
import { IsBoolean, IsInt, IsNotEmpty, IsNotEmptyObject, IsOptional, IsString, ValidateIf, ValidateNested } from 'class-validator'
9-
10-
export class FilesOnlyOfficeConfig {
11-
@IsBoolean()
12-
enabled = false
13-
14-
@IsOptional()
15-
@IsString()
16-
externalServer: string = null
17-
18-
@ValidateIf((o: FilesOnlyOfficeConfig) => o.enabled)
19-
@IsString()
20-
@IsNotEmpty()
21-
secret: string
22-
23-
@IsBoolean()
24-
verifySSL: boolean = false
25-
}
8+
import { IsBoolean, IsInt, IsNotEmpty, IsNotEmptyObject, IsString, ValidateNested } from 'class-validator'
9+
import { CollaboraOnlineConfig } from './modules/collabora-online/collabora-online.config'
10+
import { OnlyOfficeConfig } from './modules/only-office/only-office.config'
2611

2712
export class FilesConfig {
2813
@IsNotEmpty()
@@ -52,6 +37,11 @@ export class FilesConfig {
5237

5338
@IsNotEmptyObject()
5439
@ValidateNested()
55-
@Type(() => FilesOnlyOfficeConfig)
56-
onlyoffice: FilesOnlyOfficeConfig = new FilesOnlyOfficeConfig()
40+
@Type(() => OnlyOfficeConfig)
41+
onlyoffice: OnlyOfficeConfig = new OnlyOfficeConfig()
42+
43+
@IsNotEmptyObject()
44+
@ValidateNested()
45+
@Type(() => CollaboraOnlineConfig)
46+
collabora: CollaboraOnlineConfig = new CollaboraOnlineConfig()
5747
}

backend/src/applications/files/files.controller.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,11 @@ import { FastifySpaceRequest } from '../spaces/interfaces/space-request.interfac
3939
import { SpaceEnv } from '../spaces/models/space-env.model'
4040
import { GetUser } from '../users/decorators/user.decorator'
4141
import { UserModel } from '../users/models/user.model'
42-
import { FILE_OPERATION } from './constants/operations'
42+
import { FILE_OPERATION, FORCE_AS_FILE_OWNER } from './constants/operations'
4343
import { FILES_ROUTE } from './constants/routes'
4444
import { CompressFileDto, CopyMoveFileDto, DownloadFileDto, MakeFileDto, SearchFilesDto } from './dto/file-operations.dto'
4545
import { FileLockProps } from './interfaces/file-props.interface'
46+
import { FileSettings } from './interfaces/file-settings.interface'
4647
import { FileTask } from './models/file-task'
4748
import { FileContent } from './schemas/file-content.interface'
4849
import { FileRecent } from './schemas/file-recent.interface'
@@ -145,9 +146,9 @@ export class FilesController {
145146
async unlock(
146147
@GetUser() user: UserModel,
147148
@GetSpace() space: SpaceEnv,
148-
@Query('forceAsOwner', new ParseBoolPipe({ optional: true })) forceAsOwner?: boolean
149+
@Query(FORCE_AS_FILE_OWNER, new ParseBoolPipe({ optional: true })) forceAsFileOwner?: boolean
149150
): Promise<void> {
150-
return this.filesMethods.unlock(user, space, forceAsOwner)
151+
return this.filesMethods.unlock(user, space, forceAsFileOwner)
151152
}
152153

153154
@Unlock(`${FILES_ROUTE.OPERATION}/${FILE_OPERATION.UNLOCK_REQUEST}/*`)
@@ -198,6 +199,14 @@ export class FilesController {
198199
return this.filesTasksManager.createTask(FILE_OPERATION.DELETE, user, space, null, this.filesMethods.delete.name)
199200
}
200201

202+
// SETTINGS
203+
204+
@Get(FILES_ROUTE.SETTINGS)
205+
@SkipSpaceGuard()
206+
filesSettings(): FileSettings {
207+
return this.filesMethods.fileSettings()
208+
}
209+
201210
// RECENT FILES
202211

203212
@Get(FILES_ROUTE.RECENTS)

backend/src/applications/files/files.module.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,17 @@
55
*/
66

77
import { Module } from '@nestjs/common'
8+
import { configuration } from '../../configuration/config.environment'
89
import { FilesIndexerMySQL } from './adapters/files-indexer-mysql.service'
9-
import { FilesOnlyOfficeController } from './files-only-office.controller'
1010
import { FilesTasksController } from './files-tasks.controller'
1111
import { FilesController } from './files.controller'
12-
import { FilesOnlyOfficeGuard } from './guards/files-only-office.guard'
13-
import { FilesOnlyOfficeStrategy } from './guards/files-only-office.strategy'
1412
import { FilesIndexer } from './models/files-indexer'
13+
import { CollaboraOnlineModule } from './modules/collabora-online/collabora-online.module'
14+
import { OnlyOfficeModule } from './modules/only-office/only-office.module'
1515
import { FilesContentManager } from './services/files-content-manager.service'
1616
import { FilesLockManager } from './services/files-lock-manager.service'
1717
import { FilesManager } from './services/files-manager.service'
1818
import { FilesMethods } from './services/files-methods.service'
19-
import { FilesOnlyOfficeManager } from './services/files-only-office-manager.service'
2019
import { FilesParser } from './services/files-parser.service'
2120
import { FilesQueries } from './services/files-queries.service'
2221
import { FilesRecents } from './services/files-recents.service'
@@ -25,7 +24,11 @@ import { FilesSearchManager } from './services/files-search-manager.service'
2524
import { FilesTasksManager } from './services/files-tasks-manager.service'
2625

2726
@Module({
28-
controllers: [FilesController, FilesTasksController, FilesOnlyOfficeController],
27+
imports: [
28+
...(configuration.applications.files.onlyoffice.enabled ? [OnlyOfficeModule] : []),
29+
...(configuration.applications.files.collabora.enabled ? [CollaboraOnlineModule] : [])
30+
],
31+
controllers: [FilesController, FilesTasksController],
2932
providers: [
3033
FilesMethods,
3134
FilesManager,
@@ -34,9 +37,6 @@ import { FilesTasksManager } from './services/files-tasks-manager.service'
3437
FilesTasksManager,
3538
FilesScheduler,
3639
FilesRecents,
37-
FilesOnlyOfficeManager,
38-
FilesOnlyOfficeGuard,
39-
FilesOnlyOfficeStrategy,
4040
FilesParser,
4141
FilesContentManager,
4242
{ provide: FilesIndexer, useClass: FilesIndexerMySQL },

0 commit comments

Comments
 (0)