React Meteor Upload Docs to Google Drive

meteor-slingshot

Gitter

Directly and secure file-uploads to AWS S3, Google Deject Storage and others.

Install

meteor add together edgee:slingshot

Why?

There are many many packages out there that allow file uploads to S3, Google Cloud and other cloud storage services, but they normally rely on the meteor apps' server to relay the files to the deject service, which puts the server nether unnecessary load.

meteor-slingshot uploads the files straight to the cloud service from the browser without always exposing your secret access key or any other sensitive information to the client and without requiring public write access to cloud storage to the entire public.

File uploads tin not only exist restricted past file-size and file-type, but also by other stateful criteria such as the current meteor user.

Quick Example

Customer side

On the client side we can at present upload files through to the bucket:

              var              uploader              =              new              Slingshot              .              Upload              (              "myFileUploads"              )              ;              uploader              .              send              (              document              .              getElementById              (              'input'              )              .              files              [              0              ]              ,              function              (              error              ,              downloadUrl              )              {              if              (              mistake              )              {              // Log service detailed response.              panel              .              error              (              'Error uploading'              ,              uploader              .              xhr              .              response              )              ;              warning              (              error              )              ;              }              else              {              Meteor              .              users              .              update              (              Meteor              .              userId              (              )              ,              {              $button:              {              "profile.files":              downloadUrl              }              }              )              ;              }              }              )              ;            

Customer and Server

These file upload restrictions are validated on the client and then appended to the directive on the server side to enforce them:

              Slingshot              .              fileRestrictions              (              "myFileUploads"              ,              {              allowedFileTypes:              [              "image/png"              ,              "image/jpeg"              ,              "paradigm/gif"              ]              ,              maxSize:              ten              *              1024              *              1024              // ten MB (apply null for unlimited).              }              )              ;            

Important: The fileRestrictions must be alleged earlier the the directive is instantiated.

Server side

On the server we declare a directive that controls upload access rules:

              Slingshot              .              createDirective              (              "myFileUploads"              ,              Slingshot              .              S3Storage              ,              {              saucepan:              "mybucket"              ,              acl:              "public-read"              ,              authorize:              function              (              )              {              //Deny uploads if user is not logged in.              if              (              !              this              .              userId              )              {              var              bulletin              =              "Please login before posting files"              ;              throw              new              Meteor              .              Error              (              "Login Required"              ,              bulletin              )              ;              }              render              true              ;              }              ,              key:              part              (              file              )              {              //Shop file into a directory by the user'due south username.              var              user              =              Falling star              .              users              .              findOne              (              this              .              userId              )              ;              render              user              .              username              +              "/"              +              file              .              proper noun              ;              }              }              )              ;            

With the directive to a higher place, no other files than images will be allowed. The policy is directed by the meteor app server and enforced by AWS S3.

Note: If your saucepan is created in any region other than Us Standard, y'all volition need to gear up the region key in the directive. Refer the AWS Slingshot Storage Directives

Storage services

The customer side is agnostic to which storage service is used. All information technology needs for the file upload to work, is a directive proper name.

There is no limit imposed on how many directives tin exist declared for each storage service.

Storage services are pluggable in Slingshot and yous can add back up for own storage service as described in a section below.

Progress confined

Y'all tin create file upload progress confined every bit follows:

<template                              name=                              "progressBar"              >   <div                              class=                              "progress"              >     <div                              class=                              "progress-bar"                                            part=                              "progressbar"                                            aria-valuenow=                              "                {{                progress                }}                "                                            aria-valuemin=                              "0"                                            aria-valuemax=                              "100"                                            style=                              "width:                {{                progress                }}%;"              >       <span                              class=                              "sr-only"              >{{              progress              }}% Complete</span>     </div>   </div> </template>

Using the Slingshot.Upload instance read and react to the progress:

              Template              .              progressBar              .              helpers              (              {              progress:              function              (              )              {              render              Math              .              round              (              this              .              uploader              .              progress              (              )              *              100              )              ;              }              }              )              ;            

Evidence uploaded file earlier it is uploaded (latency bounty)

<template                              name=                              "myPicture"              >   <img                              src=              {{              url              }}/> </template>
              Template              .              myPicture              .              helpers              (              {              url:              function              (              )              {              //If we are uploading an epitome, pass true to download the epitome into cache.              //This will preload the image before using the remote paradigm url.              return              this              .              uploader              .              url              (              true              )              ;              }              }              )              ;            

This to prove the epitome from the local source until it is uploaded to the server. If Blob URL'south are not available it volition attempt to use FileReader to generate a base64-encoded url representing the data as a fallback.

Add meta-context to your uploads

You can add meta-context to your file-uploads, to make your requests more than specific on where the files are to be uploaded.

Consider the post-obit instance...

We take an app that features picture albums. An album belongs to a user and only that user is allowed to upload pic to it. In the cloud each album has its ain directory where its pictures are stored.

We declare our client-side uploader as follows:

              var              metaContext              =              {              albumId:              album              .              _id              }              var              uploadToMyAlbum              =              new              Slingshot              .              Upload              (              "picturealbum"              ,              metaContext              )              ;            

On the server side the directive tin now set the key appropriately and check if the user is allowed postal service pictures to the given anthology:

              Slingshot              .              createDirective              (              "picturealbum"              ,              Slingshot              .              GoogleCloud              ,              {              acl:              "public-read"              ,              authorize:              role              (              file              ,              metaContext              )              {              var              album              =              Albums              .              findOne              (              metaContext              .              albumId              )              ;              //Denied if album doesn't exist or if it is not endemic by the current user.              return              album              &&              album              .              userId              ===              this              .              userId              ;              }              ,              primal:              function              (              file              ,              metaContext              )              {              return              metaContext              .              albumId              +              "/"              +              Date              .              at present              (              )              +              "-"              +              file              .              proper name              ;              }              }              )              ;            

Manual Client Side validation

You can check if a file uploadable according to file-restrictions every bit follows:

              var              uploader              =              new              Slingshot              .              Upload              (              "myFileUploads"              )              ;              var              error              =              uploader              .              validate              (              certificate              .              getElementById              (              'input'              )              .              files              [              0              ]              )              ;              if              (              error              )              {              console              .              fault              (              error              )              ;              }            

The validate method will render null if valid and returns an Error instance if validation fails.

AWS S3

Y'all will need aAWSAccessKeyId and AWSSecretAccessKey in Falling star.settings and a bucket with the following CORS configuration:

<?xml                              version=                "one.0"                                            encoding=                "UTF-eight"              ?> <CORSConfiguration              xmlns=                "http://s3.amazonaws.com/doc/2006-03-01/"              >     <CORSRule>         <AllowedOrigin>*</AllowedOrigin>         <AllowedMethod>PUT</AllowedMethod>         <AllowedMethod>Mail</AllowedMethod>         <AllowedMethod>GET</AllowedMethod>         <AllowedMethod>Head</AllowedMethod>         <MaxAgeSeconds>3000</MaxAgeSeconds>         <AllowedHeader>*</AllowedHeader>     </CORSRule> </CORSConfiguration>

Declare AWS S3 Directives as follows:

              Slingshot              .              createDirective              (              "aws-s3-case"              ,              Slingshot              .              S3Storage              ,              {              //...              }              )              ;            

S3 with temporary AWS Credentials (Advanced)

For extra security you lot can utilize temporary credentials to sign upload requests.

              var              sts              =              new              AWS              .              STS              (              )              ;              // Using the AWS SDK to retrieve temporary credentials.              Slingshot              .              createDirective              (              'myUploads'              ,              Slingshot              .              S3Storage              .              TempCredentials              ,              {              bucket:              'myBucket'              ,              temporaryCredentials:              Meteor              .              wrapAsync              (              function              (              elapse              ,              callback              )              {              //AWS dictates that the minimum duration must be 900 seconds:              var              duration              =              Math              .              max              (              Math              .              round              (              expire              /              chiliad              )              ,              900              )              ;              sts              .              getSessionToken              (              {              DurationSeconds:              elapsing              }              ,              function              (              error              ,              issue              )              {              callback              (              error              ,              result              &&              outcome              .              Credentials              )              ;              }              )              ;              }              )              }              )              ;            

If yous are running slingshot on an EC2 instance, y'all can conveniantly retreive your access keys with AWS.EC2MetadataCredentials:

              var              credentials              =              new              AWS              .              EC2MetadataCredentials              (              )              ;              var              updateCredentials              =              Meteor              .              wrapAsync              (              credentials              .              get              ,              credentials              )              ;              Slingshot              .              createDirective              (              'myUploads'              ,              Slingshot              .              S3Storage              .              TempCredentials              ,              {              bucket:              'myBucket'              ,              temporaryCredentials:              role              (              )              {              if              (              credentials              .              needsRefresh              (              )              )              {              updateCredentials              (              )              ;              }              return              {              AccessKeyId:              credentials              .              accessKeyId              ,              SecretAccessKey:              credentials              .              secretAccessKey              ,              SessionToken:              credentials              .              sessionToken              }              ;              }              }              )              ;            

Google Cloud

Generate a private key and convert it to a .pem file using openssl:

              openssl pkcs12 -in google-cloud-service-key.p12 -nodes -nocerts > google-cloud-service-fundamental.pem                          

Setup CORS on the saucepan:

              gsutil cors gear up docs/gs-cors.json gs://mybucket                          

Save this file into the /private directory of your meteor app and add this line to your server-side code:

              Slingshot              .              GoogleCloud              .              directiveDefault              .              GoogleSecretKey              =              Assets              .              getText              (              'google-cloud-service-cardinal.pem'              )              ;            

Declare Google Deject Storage Directives as follows:

              Slingshot              .              createDirective              (              "google-cloud-case"              ,              Slingshot              .              GoogleCloud              ,              {              //...              }              )              ;            

Rackspace Cloud Files

Y'all volition need aRackspaceAccountId (your acocunt number) and RackspaceMetaDataKey in Meteor.settings.

In guild to obtain your RackspaceMetaDataKey (a.k.a. Business relationship-Meta-Temp-Url-Primal) you demand an auth-token and and then follow the instructions hither.

Note that API-Primal, Auth-Token, Meta-Data-Cardinal are not the aforementioned thing:

API-Key is what you demand to obtain an Auth-Token, which in turn is what you need to setup CORS and to set your Meta-Data-Central. The auth-token expires subsequently 24 hours.

For your directive yous need container and provide its name, region and cdn.

              Slingshot              .              createDirective              (              "rackspace-files-example"              ,              Slingshot              .              RackspaceFiles              ,              {              container:              "myContainer"              ,              //Container name.              region:              "lon3"              ,              //Region code (The default would be 'iad3').              //Y'all must ready the cdn if you lot want the files to be publicly accessible:              cdn:              "https://abcdefghije8c9d17810-ef6d926c15e2b87b22e15225c32e2e17.r19.cf5.rackcdn.com"              ,              pathPrefix:              office              (              file              )              {              //Shop file into a directory by the user'due south username.              var              user              =              Meteor              .              users              .              findOne              (              this              .              userId              )              ;              return              user              .              username              ;              }              }              )              ;            

To setup CORS you also demand to your Auth-Token from above and use:

roll -I -Ten POST -H                              'Ten-Auth-Token: yourAuthToken'                            \   -H                              'X-Container-Meta-Access-Control-Let-Origin: *'                            \   -H                              'X-Container-Meta-Access-Expose-Headers: etag location 10-timestamp x-trans-id Admission-Control-Allow-Origin'                            \   https://storage101.containerRegion.clouddrive.com/v1/MossoCloudFS_yourAccoountNumber/yourContainer

Cloudinary

Cloudinary is supported via a tertiary party package.
jimmiebtlr:cloudinary

Browser Compatibility

Currently the uploader uses XMLHttpRequest 2 to upload the files, which is not supported on Internet Explorer 9 and older versions of Internet Explorer.

This tin can be circumvented by falling dorsum to iframe uploads in future versions, if required.

Latency compensation is available in Internet Explorer x.

Security

The surreptitious fundamental never leaves the meteor app server. Nobody volition exist able to upload anything to your buckets outside of your meteor app.

Instead of using secret access keys, Slingshot uses a policy document that is sent to along with the file AWS S3 or Google Cloud Storage. This policy is signed by the secret key and contains all the restrictions that you define in the directive. By default a signed policy expires subsequently 5 minutes.

Adding Support for other storage Services

Cloud storage services are pluggable in Slingshot. You tin can add support for a deject storage service of your option. All you demand is to declare an object with the following parameters:

              MyStorageService              =              {              /**                              * Define the additional parameters that your your service uses here.                              *                              * Annotation that some parameters like maxSize are shared by all services. You do                              * non need to define those past yourself.                              */              directiveMatch:              {              accessKey:              String              ,              options:              Object              ,              foo:              Friction match              .              Optional              (              Function              )              }              ,              /**                              * Here you can ready default parameters that your service will use.                              */              directiveDefault:              {              options:              {              }              }              ,              /**                              *                              *                @param                {Object} method - This is the Meteor Method context.                              *                @param                {Object} directive - All the parameters from the directive.                              *                @param                {Object} file - Information virtually the file as gathered past the                              * browser.                              *                @param                {Object} [meta] - Meta information that was passed to the uploader.                              *                              *                @returns                {UploadInstructions}                              */              upload:              part              (              method              ,              directive              ,              file              ,              meta              )              {              var              accessKey              =              directive              .              accessKey              ;              var              fooData              =              directive              .              foo              &&              directive              .              foo              .              call              (              method              ,              file              ,              meta              )              ;              //Here you need to make sure that all parameters passed in the directive              //are going to be enforced by the server receiving the file.              return              {              // Endpoint where the file is to exist uploaded:              upload:              "https://example.com"              ,              // Download URL, one time the file uploaded:              download:              directive              .              cdn              ||              "https://case.com/"              +              file              .              proper name              ,              // POST data to be attached to the file-upload:              postData:              [              {              name:              "accessKey"              ,              value:              accessKey              }              ,              {              proper name:              "signature"              ,              value:              signature              }              //...              ]              ,              // HTTP headers to ship when uploading:              headers:              {              "10-foo-bar":              fooData              }              }              ;              }              ,              /**                              * Absolute maximum file-size allowable by the storage service.                              */              maxSize:              5              *              1024              *              1024              *              1024              }              ;            

Example Directive:

              Slingshot              .              createDirective              (              "myUploads"              ,              MyStorageService              ,              {              accessKey:              "a12345xyz"              ,              foo:              function              (              file              ,              metaContext              )              {              return              "bar"              ;              }              }              )              ;            

Dependencies

Meteor core packages:

  • underscore
  • tracker
  • reactive-var
  • check

Troubleshooting and Assist

If you are having any queries most how to apply slingshot, or how to get information technology to work with the different services or any other general questions nigh information technology, delight post a question on Stack Overflow. Yous volition become a loftier quality respond at that place much quicker than past posting an issue here on github.

Bug reports, Characteristic Requests and Pull Requests are always welcome.

API Reference

Directives

General (All Services)

qualify: Function (required unless set in File Restrictions)

maxSize: Number (required unless gear up in File Restrictions)

allowedFileTypes RegExp, Cord or Assortment (required unless set in File Restrictions)

cdn String (optional) - CDN domain for downloads. i.east. "https://d111111abcdef8.cloudfront.net"

expire Number (optional) - Number of milliseconds in which an upload authorization volition expire later the asking was made. Default is v minutes.

AWS S3 (Slingshot.S3Storage)

region Cord (optional) - Default is Meteor.settings.AWSRegion or "usa-east-ane". See AWS Regions

AWSAccessKeyId String (required) - Can also be ready in Shooting star.settings.

AWSSecretAccessKey String (required) - Can also be set in Meteor.settings.

AWS S3 with Temporary Credentials (Slingshot.S3Storage.TempCredentials)

region String (optional) - Default is Meteor.settings.AWSRegion or "us-due east-i". Run across AWS Regions

temporaryCredentials Function (required) - Function that generates temporary credentials. It takes a signle argument, which is the minumum desired expiration time in milli-seconds and it returns an object that contains AccessKeyId, SecretAccessKey and SessionToken.

Google Cloud Storage (Slingshot.GoogleCloud)

bucket Cord (required) - Proper name of bucket to apply. The default is Meteor.settings.GoogleCloudBucket.

GoogleAccessId Cord (required) - Can also be prepare in Meteor.settings.

GoogleSecretKey String (required) - Can also exist set in Shooting star.settings.

AWS S3 and Google Cloud Storage

bucket String (required) - Proper name of bucket to utilize. The default is Meteor.settings.GoogleCloudBucket. For AWS S3 the default saucepan is Shooting star.settings.S3Bucket.

bucketUrl String or Role (optional) - Override URL to which files are uploaded. If it is a function, so the first argument is the saucepan proper noun. This url also used for downloads unless a cdn is given.

cardinal String or Function (required) - Name of the file on the cloud storage service. If a function is provided, it will be called with userId in the context and its return value is used every bit the fundamental. First argument is file info and the 2d is the meta-information that can be passed by the client.

acl String (optional)

cacheControl String (optional) - RFC 2616 Cache-Control directive

contentDisposition String or Function (optional) - RFC 2616 Content-Disposition directive. Default is the uploaded file's name (inline). If it is a office and so information technology takes the same context and arguments equally the key function. Utilise null to disable.

Rackspace Cloud (Slingshot.RackspaceFiles)

RackspaceAccountId Cord (required) - Can also be set in Shooting star.settings.

RackspaceMetaDataKey Cord (required) - Can also exist set in Meteor.settings.

container String (required) - Name of container to utilize.

region String (optional) - Information Center region. The default is "iad3". See other regions

pathPrefix String or Function (required) - Similar to key for S3, only will always be appended by file.name that is provided past the client.

deleteAt Date (optional) - Absolute time when the uploaded file is to be deleted. This attribute is not enforced at all. It can be easily altered past the client

deleteAfter Number (optional) - Same as deleteAt, only relative.

File restrictions

authorize Function (optional) - Function to determines if upload is immune.

maxSize Number (optional) - Maximum file-size (in bytes). Utilise null or 0 for unlimited.

allowedFileTypes RegExp, String or Array (optional) - Allowed MIME types. Utilise nil for any file type.

jolicoeurpult1959.blogspot.com

Source: https://github.com/CulturalMe/meteor-slingshot

0 Response to "React Meteor Upload Docs to Google Drive"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel