Skip to content

Commit 22ea6a7

Browse files
committed
fix #10
1 parent a0be26e commit 22ea6a7

File tree

5 files changed

+152
-72
lines changed

5 files changed

+152
-72
lines changed

server/routers/plugins.js

Lines changed: 95 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -201,80 +201,120 @@ function createPluginFromGithub(req) {
201201
});
202202
}
203203

204-
router.post('/', (req, res) => {
204+
function createEmptyPlugin(req, metadata) {
205205
const { s3, Bucket } = S3.state()
206206

207207
const user = format(req.user.email)
208208

209-
UserManager.createUserIfNotExists(req)
210-
.then(() => {
211-
UserManager.getUser(req)
212-
.then(data => {
213-
const pluginId = crypto.randomUUID()
214-
const plugins = [
215-
...(data.plugins || []),
216-
{
217-
filename: req.body.plugin,
218-
type: req.body.type,
219-
pluginId: pluginId
209+
return new Promise(resolve => {
210+
UserManager.createUserIfNotExists(req)
211+
.then(() => {
212+
UserManager.getUser(req)
213+
.then(data => {
214+
const pluginId = crypto.randomUUID()
215+
const plugins = [
216+
...(data.plugins || []),
217+
{
218+
filename: metadata.name,
219+
type: metadata.type,
220+
pluginId: pluginId
221+
}
222+
]
223+
const params = {
224+
Bucket,
225+
Key: `${user}.json`,
226+
Body: JSON.stringify({
227+
...data,
228+
plugins
229+
})
220230
}
221-
]
222-
const params = {
223-
Bucket,
224-
Key: `${user}.json`,
225-
Body: JSON.stringify({
226-
...data,
227-
plugins
228-
})
229-
}
230231

231-
s3.send(new PutObjectCommand(params))
232-
.then(() => res
233-
.status(201)
234-
.json({
235-
plugins
236-
}))
237-
.catch(err => {
238-
console.log(err)
239-
res
240-
.status(err.$metadata.httpStatusCode)
241-
.json({
242-
error: err.Code,
243-
status: err.$metadata.httpStatusCode
232+
s3.send(new PutObjectCommand(params))
233+
.then(() => {
234+
resolve({
235+
status: 201,
236+
body: {
237+
plugins
238+
}
244239
})
245-
})
246-
})
247-
})
248-
.catch(err => {
249-
res
250-
.status(400)
251-
.json({
252-
error: err.message
240+
})
241+
.catch(err => {
242+
resolve({
243+
status: err.$metadata.httpStatusCode,
244+
body: {
245+
error: err.Code,
246+
status: err.$metadata.httpStatusCode
247+
}
248+
})
249+
})
250+
})
251+
})
252+
.catch(err => {
253+
resolve({
254+
status: 400,
255+
body: {
256+
error: err.message
257+
}
253258
})
254-
})
255-
})
259+
})
260+
})
261+
}
256262

257-
router.put('/:id', (req, res) => {
263+
function updatePluginContent(id, body) {
258264
const { s3, Bucket } = S3.state();
259265

260266
const params = {
261267
Bucket,
262-
Key: `${req.params.id}.zip`,
263-
Body: req.body
268+
Key: `${id}.zip`,
269+
Body: body
264270
}
265271

266-
s3.send(new PutObjectCommand(params))
267-
.then(() => res
268-
.status(204)
269-
.json(null))
272+
return s3.send(new PutObjectCommand(params))
273+
.then(() => ({
274+
status: 204,
275+
body: null
276+
}))
270277
.catch(err => {
271-
res
272-
.status(err.$metadata.httpStatusCode)
273-
.json({
278+
return {
279+
status: err.$metadata.httpStatusCode,
280+
body: {
274281
error: err.Code,
275282
status: err.$metadata.httpStatusCode
276-
})
283+
}
284+
}
277285
})
286+
}
287+
288+
router.post('/', async (req, res) => {
289+
290+
if (!req.body ||
291+
Object.keys(req.body).length === 0 ||
292+
(!req.body.metadata && !(req.body.plugin && req.body.type))) {
293+
return res.status(400).json({ error: 'missing body' });
294+
}
295+
296+
const out = await createEmptyPlugin(req, req.body.metadata || {
297+
name: req.body.plugin,
298+
type: req.body.type
299+
});
300+
301+
if (out.status !== 201 || !req.body.files) {
302+
return res.status(out.status).json(out.body);
303+
} else {
304+
const templatesFiles = await FileSystem.templatesFilesToJSON(req.body.metadata.type);
305+
const zip = await FileSystem.createZipFromJSONFiles(req.body.files, templatesFiles);
306+
updatePluginContent(out.body.plugins[out.body.plugins.length - 1].pluginId, zip)
307+
.then(out => {
308+
res.status(out.status).json(out.body);
309+
});
310+
}
311+
})
312+
313+
router.put('/:id', (req, res) => {
314+
updatePluginContent(req.params.id, req.body)
315+
.then(out => {
316+
res.status(out.status).json(out.body);
317+
});
278318
})
279319

280320
router.delete('/:id', async (req, res) => {

server/security/middlewares.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ const otoroshiAuthentication = (req, res, next) => {
1515
if (jwtUser) {
1616
try {
1717
const decodedToken = jwt.verify(jwtUser, secret, { algorithms: ['HS512'] });
18-
req.user = decodedToken.user || decodedToken.apikey.clientId
18+
req.user = decodedToken.user || {
19+
email: decodedToken.apikey.clientId
20+
}
1921
next()
2022
} catch (err) {
2123
console.log(err)

server/services/file-system.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const fs = require('fs-extra');
22
const path = require('path');
33
const { INFORMATIONS_FILENAME } = require('../utils');
4+
const AdmZip = require('adm-zip');
45

56
const createBuildFolder = (type, name) => {
67
if (['rust', 'js', 'ts'].includes(type)) {
@@ -86,6 +87,7 @@ const writeFiles = (files, folder, isRustBuild) => {
8687
}));
8788
}
8889

90+
8991
const storeWasm = (fromFolder, filename) => fs.move(fromFolder, pathsToPath(`/wasm/${filename}`));
9092

9193
const getLocalWasm = (id, res) => {
@@ -97,6 +99,36 @@ const getLocalWasm = (id, res) => {
9799
})
98100
}
99101

102+
const createZipFromJSONFiles = (jsonFiles, templatesFiles) => {
103+
const zip = new AdmZip();
104+
[...templatesFiles, ...jsonFiles].forEach(({ name, content }) => {
105+
zip.addFile(name, content)
106+
})
107+
108+
return zip.toBuffer()
109+
}
110+
111+
const templatesFilesToJSON = type => {
112+
const folder = path.join(process.cwd(), 'templates', 'builds', type);
113+
114+
return new Promise(resolve => fs.readdir(folder, (err, filenames) => {
115+
if (err) {
116+
return [];
117+
}
118+
119+
Promise.all(filenames.map(name => new Promise(resolve => {
120+
fs.readFile(path.join(folder, name), 'utf-8', (err, content) => {
121+
if (err) {
122+
resolve({ name, content: "" })
123+
}
124+
resolve({ name, content })
125+
});
126+
})))
127+
.then(resolve)
128+
}))
129+
130+
}
131+
100132
module.exports = {
101133
FileSystem: {
102134
writeFiles,
@@ -111,6 +143,8 @@ module.exports = {
111143
existsFile,
112144
pathsToPath,
113145
storeWasm,
114-
getLocalWasm
146+
getLocalWasm,
147+
createZipFromJSONFiles,
148+
templatesFilesToJSON
115149
}
116150
}

ui/src/FileManager.js

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ function Group({ items, folder, onFileClick, component, ...props }) {
5252
<div className='d-flex flex-column'>
5353
{component ? <Component {...props} /> :
5454
items
55-
.sort((a, b) => a.ext.localeCompare(b.ext))
55+
.sort((a, b) => a.ext?.localeCompare(b.ext))
5656
.map((item, i) => {
5757
return <File {...item}
5858
key={`item.filename-${i}`}
@@ -103,7 +103,17 @@ function FileManager({
103103

104104
return (
105105
<div className='d-flex flex-column' style={{ minWidth: 250, background: '#eee', flex: 1 }}>
106-
<Header onNewFile={onNewFile} selectedPlugin={selectedPlugin} readOnly={selectedPlugin.type === "github"} />
106+
{selectedPlugin?.filename && <h2 style={{
107+
color: '#000',
108+
fontSize: '1rem',
109+
fontWeight: 'bold',
110+
padding: '0 12px',
111+
margin: 0,
112+
height: 36,
113+
lineHeight: '36px',
114+
textTransform: 'uppercase'
115+
}}>{selectedPlugin?.filename}</h2>}
116+
{selectedPlugin.type !== "github" && <Header onNewFile={onNewFile} readOnly={selectedPlugin.type === "github"} />}
107117

108118
<div className='d-flex flex-column scroll-container mt-1'>
109119
{[...files]
@@ -151,23 +161,17 @@ function FileManager({
151161
);
152162
}
153163

154-
function Header({ onNewFile, selectedPlugin, readOnly }) {
164+
function Header({ onNewFile, readOnly }) {
155165
return <div className='d-flex justify-content-between align-items-center sidebar-header'
156166
style={{
167+
margin: '0 6px 6px',
157168
cursor: readOnly ? 'initial' : 'pointer',
158169
pointerEvents: readOnly ? 'none' : 'initial'
159170
}} onClick={onNewFile}>
160171
<div className='d-flex align-items-center'>
161-
<i className='fas fa-chess-rook me-1' />
162-
<span className='fw-bold'>{selectedPlugin?.filename}</span>
172+
<i className='fas fa-file-circle-plus p-1 me-1' />
173+
<span className='fw-bold'>New File</span>
163174
</div>
164-
165-
{!readOnly && <div style={{
166-
background: '#eee',
167-
borderRadius: 4
168-
}}>
169-
<i className='fas fa-file-circle-plus p-1' />
170-
</div>}
171175
</div>
172176
}
173177

ui/src/PluginManager.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,20 @@ class PluginManager extends React.Component {
1414

1515
return (
1616
<div className='d-flex flex-column' style={{ minWidth: 250, flex: selectedPlugin ? 0 : 1 }}>
17-
<Header onNewPlugin={onNewPlugin} reloadPlugins={props.reloadPlugins} />
17+
{!selectedPlugin && <Header onNewPlugin={onNewPlugin} reloadPlugins={props.reloadPlugins} />}
1818
{selectedPlugin && <div className='d-flex justify-content-between align-items-center sidebar-header'
1919
style={{
2020
cursor: 'pointer'
2121
}} onClick={() => props.setSelectedPlugin(undefined)}>
2222
<div className='d-flex align-items-center'>
23-
<i className='fas fa-shuffle me-1' />
23+
<i className='fas fa-chevron-left me-1' />
2424
<span className='fw-bold'>Change current plugin</span>
2525
</div>
2626
</div>}
2727
<div className='d-flex flex-column scroll-container'>
2828
{!selectedPlugin &&
2929
[...plugins]
30-
.sort((a, b) => a.type.localeCompare(b.type))
30+
.sort((a, b) => a.type?.localeCompare(b.type))
3131
.map(plugin => {
3232
return <Plugin
3333
key={plugin.pluginId || 'new'}

0 commit comments

Comments
 (0)