-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat add api endoints for file storage 2082 #4715
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Andrew Burnes <[email protected]>
🤖 This is an automated code coverage reportTotal coverage (lines): 18.23% |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, well thought-out feature with tests to boot. I added a few notes on some small changes that I think could clean up the code a little bit but overall looks great. I didn't focus too much on models since I had already seen most of that.
Haven't checked on dev yet but I'll see if I can mess with the functionality today
const { FileStorageService, Site } = require('../models'); | ||
const { isSiteOrgManager, isOrgManager, isOrgUser } = require('./utils'); | ||
|
||
const canCreateSiteStorage = async ({ id: userId }, { id: siteId }) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of canCreateSiteStorage
, canAdminCreateSiteFileStorage
, isFileStorageManager
, and isFileStorageUser
have function signatures that are nice for tests but when used in controllers require constructing an object, just to destructure it immediately. I think a "more ergonomic" signature would be fn({ userId, siteId })
or fn(userId, siteId)
. Some of these functions also return a single-property object which is immediately destructured, it might be easier to just return the property directly
const { Organization, Site } = require('../models'); | ||
const { fetchModelById } = require('../utils/queryDatabase'); | ||
|
||
const authorize = async ({ id: userId }, { id: siteId }) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment in this file regarding function signatures and return values
const { SiteFileStorageSerivce } = require('../services/file-storage'); | ||
const badRequest = require('../responses/badRequest'); | ||
|
||
module.exports = wrapHandlers({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we need to create the service/client in each method (to ensure we have s3 credentials), there's a decent chunk of repeated code throughout the controller:
const siteStorageService = new SiteFileStorageSerivce(fileStorageService, user.id);
const client = await siteStorageService.createClient();
const results = await client.<some method> ...
For now it might be nice to wrap this in a helper function to DRY the code a bit. In the future, we could potentially optimize this more by caching the S3 credentials to avoid needing to fetch them on each request. (but for now it feels like premature optimization)
@@ -0,0 +1,6 @@ | |||
const multer = require('multer'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any concerns with using this package because of age?
return result; | ||
} | ||
|
||
async deleteDirectory() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be removed?
const limit = toInt(params.limit) || 25; | ||
const page = toInt(params.page) || 1; | ||
const offset = limit * (page - 1); | ||
|
||
const pQuery = { | ||
limit, | ||
offset, | ||
order: [['createdAt', 'DESC']], | ||
order: [order], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might have already been incorrect but api/admin/controllers/domain.js
uses the paginate function twice with order
supplied in the query
; I'd check that this doesn't create two separate sorts
|
||
const [base, extension] = splitFileExt(str); | ||
|
||
if (str.length > 200) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (str.length > 200) { | |
if (str.length > len) { |
const data = serializeFileStorageService(fss); | ||
return res.send(data); | ||
} catch (error) { | ||
return res.status(error.status).send(error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One issue with this pattern is that unhandled errors won't be logged anywhere, it will first show that it doesn't have an associated status:
TypeError: Invalid status code: undefined. Status code must be an intege
1fba65f
to
84a7e3e
Compare
Changes proposed in this pull request:
security considerations
Adds api endpoints for managing file storage service