mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-23 16:56:07 +00:00
270 lines
8.1 KiB
TypeScript
270 lines
8.1 KiB
TypeScript
//
|
|
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
|
// Copyright © 2021 Hardcore Engineering Inc.
|
|
//
|
|
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License. You may
|
|
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
//
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
|
|
import { resolve, join } from 'path'
|
|
import https from 'https'
|
|
import express from 'express'
|
|
import fileUpload, { UploadedFile } from 'express-fileupload'
|
|
import cors from 'cors'
|
|
import { v4 as uuid } from 'uuid'
|
|
import { decode } from 'jwt-simple'
|
|
|
|
import { Space, Ref, Doc, Account, generateId } from '@anticrm/core'
|
|
// import { TxFactory } from '@anticrm/core'
|
|
import type { Token, IndexedDoc } from '@anticrm/server-core'
|
|
import { createElasticAdapter } from '@anticrm/elastic'
|
|
import chunter from '@anticrm/chunter'
|
|
// import { createContributingClient } from '@anticrm/contrib'
|
|
|
|
import { Client, ItemBucketMetadata } from 'minio'
|
|
|
|
// import { createElasticAdapter } from '@anticrm/elastic'
|
|
|
|
// const BUCKET = 'anticrm-upload-9e4e89c'
|
|
|
|
// async function awsUpload (file: UploadedFile): Promise<string> {
|
|
// const id = uuid()
|
|
// const s3 = new S3()
|
|
// const resp = await s3.upload({
|
|
// Bucket: BUCKET,
|
|
// Key: id,
|
|
// Body: file.data,
|
|
// ContentType: file.mimetype,
|
|
// ACL: 'public-read'
|
|
// }).promise()
|
|
// console.log(resp)
|
|
// return id
|
|
// }
|
|
|
|
async function minioUpload (minio: Client, workspace: string, file: UploadedFile): Promise<string> {
|
|
const id = uuid()
|
|
const meta: ItemBucketMetadata = {
|
|
'Content-Type': file.mimetype
|
|
}
|
|
|
|
const resp = await minio.putObject(workspace, id, file.data, file.size, meta)
|
|
|
|
console.log(resp)
|
|
return id
|
|
}
|
|
|
|
// async function createAttachment (endpoint: string, token: string, account: Ref<Account>, space: Ref<Space>, attachedTo: Ref<Doc>, collection: string, name: string, file: string): Promise<void> {
|
|
// const txFactory = new TxFactory(account)
|
|
// const tx = txFactory.createTxCreateDoc(chunter.class.Attachment, space, {
|
|
// attachedTo,
|
|
// collection,
|
|
// name,
|
|
// file
|
|
// })
|
|
// const url = new URL(`/${token}`, endpoint)
|
|
// const client = await createContributingClient(url.href)
|
|
// await client.tx(tx)
|
|
// client.close()
|
|
// }
|
|
|
|
/**
|
|
* @public
|
|
* @param port -
|
|
*/
|
|
export function start (transactorEndpoint: string, elasticUrl: string, minio: Client, port: number): void {
|
|
const app = express()
|
|
|
|
app.use(cors())
|
|
app.use(fileUpload())
|
|
|
|
const dist = resolve(__dirname, 'dist')
|
|
console.log('serving static files from', dist)
|
|
app.use(express.static(dist, { maxAge: '10m' }))
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
app.get('/files', async (req, res) => {
|
|
try {
|
|
const token = req.query.token as string
|
|
const payload = decode(token, 'secret', false) as Token
|
|
const uuid = req.query.file as string
|
|
|
|
const stat = await minio.statObject(payload.workspace, uuid)
|
|
minio.getObject(payload.workspace, uuid, function (err, dataStream) {
|
|
if (err !== null) {
|
|
return console.log(err)
|
|
}
|
|
res.status(200)
|
|
|
|
const contentType = stat.metaData['content-type']
|
|
if (contentType !== undefined) {
|
|
res.setHeader('Content-Type', contentType)
|
|
}
|
|
|
|
dataStream.on('data', function (chunk) {
|
|
res.write(chunk)
|
|
})
|
|
dataStream.on('end', function () {
|
|
res.end()
|
|
})
|
|
dataStream.on('error', function (err) {
|
|
console.log(err)
|
|
})
|
|
})
|
|
} catch (error) {
|
|
console.log(error)
|
|
res.status(500).send()
|
|
}
|
|
})
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
app.post('/files', async (req, res) => {
|
|
const file = req.files?.file as UploadedFile
|
|
|
|
if (file === undefined) {
|
|
res.status(400).send()
|
|
return
|
|
}
|
|
|
|
const authHeader = req.headers.authorization
|
|
if (authHeader === undefined) {
|
|
res.status(403).send()
|
|
return
|
|
}
|
|
|
|
try {
|
|
const token = authHeader.split(' ')[1]
|
|
const payload = decode(token ?? '', 'secret', false) as Token
|
|
// const fileId = await awsUpload(file as UploadedFile)
|
|
const uuid = await minioUpload(minio, payload.workspace, file)
|
|
console.log('uploaded uuid', uuid)
|
|
|
|
const name = req.query.name as string
|
|
const space = req.query.space as Ref<Space>
|
|
const attachedTo = req.query.attachedTo as Ref<Doc>
|
|
// const name = req.query.name as string
|
|
|
|
// await createAttachment(
|
|
// transactorEndpoint,
|
|
// token,
|
|
// 'core:account:System' as Ref<Account>,
|
|
// space,
|
|
// attachedTo,
|
|
// collection,
|
|
// name,
|
|
// fileId
|
|
// )
|
|
|
|
const elastic = await createElasticAdapter(elasticUrl, payload.workspace)
|
|
|
|
const indexedDoc: IndexedDoc = {
|
|
id: generateId() + '/attachments/' + name,
|
|
_class: chunter.class.Attachment,
|
|
space,
|
|
modifiedOn: Date.now(),
|
|
modifiedBy: 'core:account:System' as Ref<Account>,
|
|
attachedTo,
|
|
data: file.data.toString('base64')
|
|
}
|
|
|
|
await elastic.index(indexedDoc)
|
|
|
|
res.status(200).send(uuid)
|
|
} catch (error) {
|
|
console.log(error)
|
|
res.status(500).send()
|
|
}
|
|
})
|
|
|
|
app.get('/import', (req, res) => {
|
|
const authHeader = req.headers.authorization
|
|
if (authHeader === undefined) {
|
|
res.status(403).send()
|
|
return
|
|
}
|
|
const token = authHeader.split(' ')[1]
|
|
const payload = decode(token ?? '', 'secret', false) as Token
|
|
const url = req.query.url as string
|
|
const cookie = req.query.cookie as string | undefined
|
|
const attachedTo = req.query.attachedTo as Ref<Doc> | undefined
|
|
|
|
console.log('importing from', url)
|
|
console.log('cookie', cookie)
|
|
|
|
const options = cookie !== undefined
|
|
? {
|
|
headers: {
|
|
Cookie: cookie
|
|
}
|
|
}
|
|
: {}
|
|
|
|
https.get(url, options, response => {
|
|
console.log('status', response.statusCode)
|
|
if (response.statusCode !== 200) {
|
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
res.status(500).send(`server returned ${response.statusCode}`)
|
|
return
|
|
}
|
|
const id = uuid()
|
|
const contentType = response.headers['content-type']
|
|
const meta: ItemBucketMetadata = {
|
|
'Content-Type': contentType
|
|
}
|
|
const data: Buffer[] = []
|
|
response.on('data', function (chunk) {
|
|
data.push(chunk)
|
|
}).on('end', function () {
|
|
const buffer = Buffer.concat(data)
|
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
minio.putObject(payload.workspace, id, buffer, 0, meta, async (err, objInfo) => {
|
|
if (err !== null) {
|
|
console.log('minio putObject error', err)
|
|
res.status(500).send(err)
|
|
} else {
|
|
console.log('uploaded uuid', id)
|
|
|
|
if (attachedTo !== undefined) {
|
|
const space = req.query.space as Ref<Space>
|
|
const elastic = await createElasticAdapter(elasticUrl, payload.workspace)
|
|
|
|
const indexedDoc: IndexedDoc = {
|
|
id: generateId() + '/attachments/' + 'Profile.pdf',
|
|
_class: chunter.class.Attachment,
|
|
space,
|
|
modifiedOn: Date.now(),
|
|
modifiedBy: 'core:account:System' as Ref<Account>,
|
|
attachedTo,
|
|
data: buffer.toString('base64')
|
|
}
|
|
|
|
await elastic.index(indexedDoc)
|
|
}
|
|
|
|
res.status(200).send({
|
|
id,
|
|
contentType,
|
|
size: data.length
|
|
})
|
|
}
|
|
})
|
|
}).on('error', function (err) {
|
|
res.status(500).send(err)
|
|
})
|
|
})
|
|
})
|
|
|
|
app.get('*', function (request, response) {
|
|
response.sendFile(join(dist, 'index.html'))
|
|
})
|
|
|
|
app.listen(port)
|
|
}
|