Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dev/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ services:
- REGION=cockroach
- QUEUE_CONFIG=${QUEUE_CONFIG}
- OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4318/v1/traces
- SECURE=true
restart: unless-stopped
hulylake:
image: hardcoreeng/hulylake
Expand Down
10 changes: 10 additions & 0 deletions foundations/core/packages/storage-client/src/client/datalake.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ import { concatLink } from '@hcengineering/core'
import { FileStorage, FileStorageUploadOptions } from '../types'
import { uploadMultipart, uploadXhr } from '../upload'

const getPathname = (url: string): string => {
const base = window?.location?.href !== undefined ? window.location.href : 'http://localhost'
return new URL(url, base).pathname
}

/** @public */
export class DatalakeStorage implements FileStorage {
constructor (private readonly baseUrl: string) {}
Expand All @@ -26,6 +31,11 @@ export class DatalakeStorage implements FileStorage {
return concatLink(this.baseUrl, path)
}

getCookiePath (workspace: string): string {
const url = concatLink(this.baseUrl, `/blob/${workspace}`)
return getPathname(url)
}

async getFileMeta (token: string, workspace: string, file: string): Promise<Record<string, any>> {
const url = concatLink(this.baseUrl, `/meta/${encodeURIComponent(workspace)}/${encodeURIComponent(file)}`)
try {
Expand Down
10 changes: 10 additions & 0 deletions foundations/core/packages/storage-client/src/client/front.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ import { concatLink } from '@hcengineering/core'
import { FileStorage, FileStorageUploadOptions } from '../types'
import { uploadXhr } from '../upload'

const getPathname = (url: string): string => {
const base = window?.location?.href !== undefined ? window.location.href : 'http://localhost'
return new URL(url, base).pathname
}

/** @public */
export class FrontStorage implements FileStorage {
constructor (private readonly baseUrl: string) {}
Expand All @@ -26,6 +31,11 @@ export class FrontStorage implements FileStorage {
return concatLink(this.baseUrl, path)
}

getCookiePath (workspace: string): string {
const url = concatLink(this.baseUrl, `/${workspace}`)
return getPathname(url)
}

async getFileMeta (token: string, workspace: string, file: string): Promise<Record<string, any>> {
return {}
}
Expand Down
10 changes: 10 additions & 0 deletions foundations/core/packages/storage-client/src/client/hulylake.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ import { concatLink } from '@hcengineering/core'
import { FileStorage, FileStorageUploadOptions } from '../types'
import { uploadXhr } from '../upload'

const getPathname = (url: string): string => {
const base = window?.location?.href !== undefined ? window.location.href : 'http://localhost'
return new URL(url, base).pathname
}

/** @public */
export class HulylakeStorage implements FileStorage {
constructor (private readonly baseUrl: string) {}
Expand All @@ -26,6 +31,11 @@ export class HulylakeStorage implements FileStorage {
return concatLink(this.baseUrl, path)
}

getCookiePath (workspace: string): string {
const url = concatLink(this.baseUrl, `/api/${workspace}`)
return getPathname(url)
}

async getFileMeta (token: string, workspace: string, file: string): Promise<Record<string, any>> {
return {}
}
Expand Down
1 change: 1 addition & 0 deletions foundations/core/packages/storage-client/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface FileStorageUploadOptions {
/** @public */
export interface FileStorage {
getFileUrl: (workspace: string, file: string, filename?: string) => string
getCookiePath: (workspace: string) => string
getFileMeta: (token: string, workspace: string, file: string) => Promise<Record<string, any>>
uploadFile: (
token: string,
Expand Down
22 changes: 13 additions & 9 deletions packages/presentation/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -891,15 +891,19 @@ export function isSpaceClass (_class: Ref<Class<Doc>>): boolean {
}

export function setPresentationCookie (token: string, workspaceUuid: WorkspaceUuid): void {
function setToken (path: string): void {
const res =
encodeURIComponent(plugin.metadata.Token.replaceAll(':', '-')) +
'=' +
encodeURIComponent(token) +
`; path=${path}`
document.cookie = res
}
setToken('/files/' + workspaceUuid)
const cookieName = encodeURIComponent(plugin.metadata.Token.replaceAll(':', '-'))
const cookieValue = encodeURIComponent(token)

const storage = getMetadata(plugin.metadata.FileStorage)
if (storage !== undefined) {
let path = `/files/${workspaceUuid}`
try {
path = storage.getCookiePath(workspaceUuid)
} catch {}

const normalized = path.startsWith('/') ? path : `/${path}`
document.cookie = `${cookieName}=${cookieValue}; path=${normalized}`
}
}

export const upgradeDownloadProgress = writable(-1)
Expand Down
2 changes: 2 additions & 0 deletions services/datalake/pod-datalake/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface Config {
DbUrl: string
Buckets: BucketConfig[]
CleanupInterval: number
Secure: boolean
Readonly: boolean
Cache: CacheConfig
}
Expand Down Expand Up @@ -86,6 +87,7 @@ const config: Config = (() => {
AccountsUrl: process.env.ACCOUNTS_URL,
DbUrl: process.env.DB_URL,
Buckets: parseBucketsConfig(process.env.BUCKETS),
Secure: process.env.SECURE === 'true',
Readonly: process.env.READONLY === 'true',
Cache: {
enabled: process.env.CACHE_ENABLED !== 'false',
Expand Down
8 changes: 8 additions & 0 deletions services/datalake/pod-datalake/src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ export const keepAlive = (options: KeepAliveOptions): RequestHandler => {
}
}

export const withOptionalAuth = (secure: boolean): RequestHandler => {
return secure
? withAuthorization
: (req: Request, res: Response, next: NextFunction) => {
next()
}
}

export const withAdminAuthorization = (req: RequestWithAuth, res: Response, next: NextFunction): void => {
try {
const token = extractToken(req.headers)
Expand Down
38 changes: 32 additions & 6 deletions services/datalake/pod-datalake/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ import {
withAuthorization,
withBlob,
withWorkspace,
withReadonly
withReadonly,
withOptionalAuth
} from './middleware'
import {
handleBlobDelete,
Expand Down Expand Up @@ -176,13 +177,33 @@ export async function createServer (

app.get('/blob/:workspace', withAdminAuthorization, withWorkspace, wrapRequest(ctx, 'listBlobs', handleBlobList))

app.head('/blob/:workspace/:name', withBlob, wrapRequest(ctx, 'headBlob', handleBlobHead))
app.head(
'/blob/:workspace/:name',
withOptionalAuth(config.Secure),
withBlob,
wrapRequest(ctx, 'headBlob', handleBlobHead)
)

app.head('/blob/:workspace/:name/:filename', withBlob, wrapRequest(ctx, 'headBlob', handleBlobHead))
app.head(
'/blob/:workspace/:name/:filename',
withOptionalAuth(config.Secure),
withBlob,
wrapRequest(ctx, 'headBlob', handleBlobHead)
)

app.get('/blob/:workspace/:name', withBlob, wrapRequest(ctx, 'getBlob', handleBlobGet))
app.get(
'/blob/:workspace/:name',
withOptionalAuth(config.Secure),
withBlob,
wrapRequest(ctx, 'getBlob', handleBlobGet)
)

app.get('/blob/:workspace/:name/:filename', withBlob, wrapRequest(ctx, 'getBlob', handleBlobGet))
app.get(
'/blob/:workspace/:name/:filename',
withOptionalAuth(config.Secure),
withBlob,
wrapRequest(ctx, 'getBlob', handleBlobGet)
)

app.delete('/blob/:workspace/:name', withAuthorization, withBlob, wrapRequest(ctx, 'deleteBlob', handleBlobDelete))

Expand All @@ -206,7 +227,12 @@ export async function createServer (

// Blob meta

app.get('/meta/:workspace/:name', withBlob, wrapRequest(ctx, 'getMeta', handleMetaGet))
app.get(
'/meta/:workspace/:name',
withOptionalAuth(config.Secure),
withBlob,
wrapRequest(ctx, 'getMeta', handleMetaGet)
)

app.put('/meta/:workspace/:name', withAuthorization, withBlob, wrapRequest(ctx, 'putMeta', handleMetaPut))

Expand Down
Loading