In this guide, we will create a new collection with file field that will be saved in the public folder in the server, after you finish this guide you can change the storage in google-cloud or aws
1 - Generate a new service
Create a new mongoose service that going to record all the files.
in this example we going to call the service 'organizations-files'
feathers generate service
? What kind of service is it? Mongoose
? What is the name of the service? organizations-files
? Which path should the service be registered on? /organizations-files
? Does the service require authentication? No
2 - Create new validators file
Create organizations-file.validators.js in the validators folder
path: src > validators > organizations-files.validators.js
const {Joi, enums} = require('feathers-mongoose-casl');
const getJoiObject = function(withRequired) {
const required = withRequired ? 'required' : 'optional';
return Joi.object({
// Data from user
displayName: Joi.string()[required](),
// File will be the file url in the storage - the uploadMiddleware will handle this value
file: Joi.string().meta({ dashboard: { doc: {inputType: 'file'}, list: {type: 'link'} } }),
// Data from the file
originalName: Joi.string(),
// The user that uplaod the file
user: Joi.objectId()
.meta({ type: 'ObjectId', ref: 'users', displayKey: 'email' })
.meta({ dashboard: { doc: {readOnly: true} } }),
// Data from the upload service
fileId: Joi.string().meta({ dashboard: { hide: 1 }}),
storage: Joi.string().valid(
enums.STORAGE_TYPES['local-public'], // When file saved on local-storage
enums.STORAGE_TYPES['others'], // When user pass link to file
).meta({ dashboard: { hide: 1 }})
});
};
module.exports = getJoiObject;
3. Add service middleware
Inside the organizations-files.service.js , add the uploadMiddleware
path : src > services > organizations-files > organizations-files.service.js
We have set in the example sys_admin ability - change it to your needs
uploadMiddleware
// Initializes the `organizations-files` service on path `/organizations-files`
const createModel = require('../../models/organizations-files.model');
const hooks = require('./organizations-files.hooks');
const { createService, STORAGE_TYPES, uploadMiddleware} = require('feathers-mongoose-casl');
module.exports = function (app) {
const Model = createModel(app);
const paginate = app.get('paginate');
const options = {
Model,
paginate,
serviceRules: [
{
actions: ['manage'],
roles: ['sys_admin']
}
]
};
// Initialize our service with any options it requires
app.use('/organizations-files',
uploadMiddleware({
app,
fileKeyName: 'file',
serviceName: 'organizations-files',
storageService: STORAGE_TYPES['local-public'],
publicRead: false,
mimetypes: null // optional - array of mimetypes to allow
}),
createService(options));
// Get our initialized service so that we can register hooks
const service = app.service('organizations-files');
service.hooks(hooks);
};
4 - Update service model
path: src > models > organizations-files.model.js
//organizations-files-model.js - A mongoose model
//
// See http://mongoosejs.com/docs/models.html
// for more of what you can do here.
const organizationFilesValidators = require('../validators/organizations-files.validators');
const { createModelFromJoi } = require('../feathers-mongoose-casl');
module.exports = function (app) {
return createModelFromJoi(app, 'organizations-files',organizationFilesValidators);
};
const { services } = require('feathers-mongoose-casl');
module.exports = function (app) {
...
app.configure(services.uploads); // uploads file to aws/google or to local folder.(Not exposed to the client)
}
7 - Validate config file
path: config\default.json
Check that your not missing this in your configuration file
{
"host": "localhost",
"port": 3030,
"public": "../public/",
"s3": { // Optional - only if you want to use s3
"bucket": "bucket....",
"accessKeyId": "accessKeyId....",
"secretAccessKey": "secretAccessKey....",
"signedUrlExpires" : 900
},
"google-cloud": { // Optional - only if you want to use google-cloud
"projectId": "google-cloud-id",
"bucket": "MyCompany-dev",
"keyFilename": "../src/secret-files/google-key.json", /* The place you save your google json file*/
"signedUrlExpires" : 900
},
"feathers-mongoose-casl": {
...
"privateFolder": "../private-files",
"privateFilesAbilityCache": {
"enabled": true,
"local-config": {
"max": 100,
"maxAge": 3600000
}
},
"uploads": {
"services": {
"s3": false,
"local-private": true,
"local-public": true,
"google-cloud": false
},
"defaultFileService": "local-private",
"blockDeleteDocumentWhenDeleteFileFailed": false,
"blockUpdateDocumentWhenReplaceFileFailed": false
}
}