adobe / aio-lib-photoshop-api

Adobe I/O Photoshop API SDK
Apache License 2.0
26 stars 11 forks source link

Unable to upload the outputs - Access Is Forbidden #41

Open velara3 opened 10 months ago

velara3 commented 10 months ago

When I try to create a rendition I am getting the following error:

{
  code: 403,
  details: [
    {
      name: 'https://s3.amazonaws.com/...',
      reason: 'Unable to upload the outputs'
    }
  ],
  title: 'Access Is Forbidden',
  type: 'AuthForbidden'
}

Here is the code I'm using:

const util = require('util');
const stream = require('stream');
const pipeline = util.promisify(stream.pipeline);
const sdk = require('@adobe/aio-lib-photoshop-api');

createRenditionOfPSD() {

      // GENERATE A NEW TOKEN
      const authDetails: string = await this.generateIMSToken(clientIdAndApiKey, clientSecret);
      let authInfo = JSON.parse(authDetails);
      authToken = authInfo.access_token;

      // CREATE PS API OBJECT
      const client = await sdk.init(ims, clientIdAndApiKey, authToken);

      // GET SIGNED URL
      var signedPSDGetURL = await getSignedUrl(key, bucket);

      // CREATE SIGNED URL FOR SAVING THE OUTPUT
      var psdImageKey = "output-of-rendition" + ".png";
      //var signedOutputURL = await getSignedPutUrl(psdImageKey, bucket);
      var signedOutputURL = await getSignedPostUrl(psdImageKey, bucket);

      // CREATE DOCUMENT RENDITION
      var psdInputOptions = {
        href: signedPSDGetURL,
        storage: sdk.Storage.EXTERNAL
      }

      var psdOutputOptions = {
        href: signedPutURL,
        type: sdk.MimeType.PNG,
        storage: sdk.Storage.EXTERNAL,
        overwrite: true
      }

      const renditionResults = await client.createRendition(psdInputOptions, psdOutputOptions);
      console.log(renditionResults);

      var outputs = psdRenditionResults.outputs;

      for (var output in outputs) {
        var outputItem = outputs[output];
        var status = outputItem.status;

        if (status=="failed") {
          var errors = outputItem.errors;
          console.log(errors);
        }
        log(output)
      }
}

The results:

Job {
  getJobStatus: [Function: bound __getJobStatus] AsyncFunction,
  url: 'https://image.adobe.io/pie/psdService/status/....',
  jobId: '...',
  outputs: [
    {
      input: 'https://s3.amazonaws.com/...',
      status: 'failed',
      created: '...',
      modified: '...',
      errors: [Object]
    }
  ],
  _links: {
    self: {
      href: 'https://image.adobe.io/pie/psdService/status/...'
    }
  }
}

The get signed PUT url and get signed Post URL are below:

export async function getSignedPutUrl(key: string, bucket: string, expireAfterMinutes: number = 0, options = null):Promise<string>{
    const s3 = new AWS.S3();
    var params = {
        Bucket: bucket,
        Key: key
    };

    if (options) {
        params = Object.assign(params, options);
    }

    const url = await s3.getSignedUrlPromise('putObject', params);
    return url;
}

export async function getSignedPostUrl(key: string, bucket: string, expireAfterMinutes: number = 0, options = null):Promise<string>{
    const s3 = new AWS.S3();
    var params = {
        Bucket: bucket,
        Fields: {
          Key: key,
          ContentType: "application/octet-stream",
        }
    };

    if (options) {
        params = Object.assign(params, options);
    }

    const presignedPost = await s3.createPresignedPost(params);
    const url = presignedPost.url;
    return url;
}
velara3 commented 10 months ago

This post says that the sender needs to match the parameters exactly. Same content type, same headers, etc.

When PS API posts the output results to S3 what is the server sending exactly? What content type? What headers? Is it a put method or a post method? Where are the examples for posting to S3?