keystonejs / keystone-storage-adapter-s3

⚠️ Archived - Legacy S3 Storage Adapter for KeystoneJS
MIT License
17 stars 55 forks source link

S3 filenames not working correctly? #6

Closed jstockwin closed 8 years ago

jstockwin commented 8 years ago

I've just started trying to migrate an app to keystone v4.0.0-beta. I've currently got a working s3 setup. However, now I've changed to using keystone-storage-adapter-s3, the uploaded files on S3 have strange filenames, and these file names do not match what is stored in S3.

The following is going to be a wall of code, but I figured I should provide all possible info.

My model is as follows:

var keystone = require('keystone');
var Types = keystone.Field.Types;

/**
 * File Model
 * ==========
 */

var File = new keystone.List('File', {
    autokey: { path: 'slug', from: 'name', unique: true },
    track: true,
});

var storage = new keystone.Storage({
    adapter: require('keystone-storage-adapter-s3'),
    s3: {
        path: process.env.S3_BUCKET,
        region: process.env.S3_REGION,
        headers: {
            'x-amz-acl': 'private',
        },
    },
    schema: {
        bucket: true, // optional; store the bucket the file was uploaded to in your db
        etag: true, // optional; store the etag for the resource
        path: true, // optional; store the path of the file in your db
        url: false, // optional; generate & store a public URL
    },
});

File.add({
    name: { type: String, required: true },
    file: {
        type: Types.File,
        storage: storage,
        filename: function (item, file) {
            return encodeURI(item._id + item.name);
        },
        format: function (item, file) {
            return '<pre>' + JSON.stringify(file, false, 2) + '</pre>'
                    + '<img src="' + file.url + '" style="max-width: 300px">';
        },
    },
    folder: { type: Types.Relationship, ref: 'Folder', many: false },
    mimetype: { type: String, hidden: true },
});

File.schema.pre('save', function (next) {
    if (this.file.filetype !== undefined) {
        this.mimetype = convert(this.file.filetype);
    }
    next();
});

File.defaultColumns = 'name, folder, author, lastModifiedDate';
File.register();

I uploaded a file, which I called testing, however this is what it looks like on S3:

Bucket: jstockwin-development
Name:   D:\Documents\Development\GitHub\students4students\jstockwin-development\nJmJPmxQdzsjygqw.pdf
Link:   <HIDDEN>
Size:   111495
Last Modified:  Sun Aug 28 11:42:30 GMT+100 2016
Owner:  jstockwin2
ETag:   6584aab099ef04293e204adb3b935bd0

Note that D:\Documents\Development\GitHub\students4students\ is where my keystone app is stored locally, and not where the file is being uploaded from....

However, on keystone, the file looks like this:

{ _id: 57c2c00c148fbb401c470eac,
  updatedAt: 2016-08-28T10:42:29.086Z,
  createdAt: 2016-08-28T10:42:20.028Z,
  slug: 'testing',
  name: 'testing',
  __v: 0,
  file: 
   { mimetype: 'application/pdf',
     size: 111495,
     filename: 'nJmJPmxQdzsjygqw.pdf',
     etag: '"6584aab099ef04293e204adb3b935bd0"',
     bucket: 'jstockwin-development' } }

So when I try to get the file, which I do using aws-sdk, I'm essentially getting a 404 error. (The specified key does not exist).

Sorry if it's me doing something wrong :)

cetchells commented 8 years ago

I have the same issue, its a windows specific problem when the filename is resolved. From node path "The path.posix property provides access to POSIX specific implementations of the path methods." Change line 92 return pathlib.posix.resolve(path, file.filename); fixes it for me.

jstockwin commented 8 years ago

@cetchells Thanks for looking in to this! If you've already made that change, would you mind submitting a pull request to fix this?