123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.IAPValidationRouter = void 0;
- var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter"));
- var _node = _interopRequireDefault(require("parse/node"));
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
- const request = require('../request');
- const rest = require('../rest');
- // TODO move validation logic in IAPValidationController
- const IAP_SANDBOX_URL = 'https://sandbox.itunes.apple.com/verifyReceipt';
- const IAP_PRODUCTION_URL = 'https://buy.itunes.apple.com/verifyReceipt';
- const APP_STORE_ERRORS = {
- 21000: 'The App Store could not read the JSON object you provided.',
- 21002: 'The data in the receipt-data property was malformed or missing.',
- 21003: 'The receipt could not be authenticated.',
- 21004: 'The shared secret you provided does not match the shared secret on file for your account.',
- 21005: 'The receipt server is not currently available.',
- 21006: 'This receipt is valid but the subscription has expired.',
- 21007: 'This receipt is from the test environment, but it was sent to the production environment for verification. Send it to the test environment instead.',
- 21008: 'This receipt is from the production environment, but it was sent to the test environment for verification. Send it to the production environment instead.'
- };
- function appStoreError(status) {
- status = parseInt(status);
- var errorString = APP_STORE_ERRORS[status] || 'unknown error.';
- return {
- status: status,
- error: errorString
- };
- }
- function validateWithAppStore(url, receipt) {
- return request({
- url: url,
- method: 'POST',
- body: {
- 'receipt-data': receipt
- },
- headers: {
- 'Content-Type': 'application/json'
- }
- }).then(httpResponse => {
- const body = httpResponse.data;
- if (body && body.status === 0) {
- // No need to pass anything, status is OK
- return;
- }
- // receipt is from test and should go to test
- throw body;
- });
- }
- function getFileForProductIdentifier(productIdentifier, req) {
- return rest.find(req.config, req.auth, '_Product', {
- productIdentifier: productIdentifier
- }, undefined, req.info.clientSDK, req.info.context).then(function (result) {
- const products = result.results;
- if (!products || products.length != 1) {
- // Error not found or too many
- throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.');
- }
- var download = products[0].download;
- return Promise.resolve({
- response: download
- });
- });
- }
- class IAPValidationRouter extends _PromiseRouter.default {
- handleRequest(req) {
- let receipt = req.body.receipt;
- const productIdentifier = req.body.productIdentifier;
- if (!receipt || !productIdentifier) {
- // TODO: Error, malformed request
- throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'missing receipt or productIdentifier');
- }
- // Transform the object if there
- // otherwise assume it's in Base64 already
- if (typeof receipt == 'object') {
- if (receipt['__type'] == 'Bytes') {
- receipt = receipt.base64;
- }
- }
- if (process.env.TESTING == '1' && req.body.bypassAppStoreValidation) {
- return getFileForProductIdentifier(productIdentifier, req);
- }
- function successCallback() {
- return getFileForProductIdentifier(productIdentifier, req);
- }
- function errorCallback(error) {
- return Promise.resolve({
- response: appStoreError(error.status)
- });
- }
- return validateWithAppStore(IAP_PRODUCTION_URL, receipt).then(() => {
- return successCallback();
- }, error => {
- if (error.status == 21007) {
- return validateWithAppStore(IAP_SANDBOX_URL, receipt).then(() => {
- return successCallback();
- }, error => {
- return errorCallback(error);
- });
- }
- return errorCallback(error);
- });
- }
- mountRoutes() {
- this.route('POST', '/validate_purchase', this.handleRequest);
- }
- }
- exports.IAPValidationRouter = IAPValidationRouter;
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfUHJvbWlzZVJvdXRlciIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiX25vZGUiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJyZXF1ZXN0IiwicmVzdCIsIklBUF9TQU5EQk9YX1VSTCIsIklBUF9QUk9EVUNUSU9OX1VSTCIsIkFQUF9TVE9SRV9FUlJPUlMiLCJhcHBTdG9yZUVycm9yIiwic3RhdHVzIiwicGFyc2VJbnQiLCJlcnJvclN0cmluZyIsImVycm9yIiwidmFsaWRhdGVXaXRoQXBwU3RvcmUiLCJ1cmwiLCJyZWNlaXB0IiwibWV0aG9kIiwiYm9keSIsImhlYWRlcnMiLCJ0aGVuIiwiaHR0cFJlc3BvbnNlIiwiZGF0YSIsImdldEZpbGVGb3JQcm9kdWN0SWRlbnRpZmllciIsInByb2R1Y3RJZGVudGlmaWVyIiwicmVxIiwiZmluZCIsImNvbmZpZyIsImF1dGgiLCJ1bmRlZmluZWQiLCJpbmZvIiwiY2xpZW50U0RLIiwiY29udGV4dCIsInJlc3VsdCIsInByb2R1Y3RzIiwicmVzdWx0cyIsImxlbmd0aCIsIlBhcnNlIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiZG93bmxvYWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlc3BvbnNlIiwiSUFQVmFsaWRhdGlvblJvdXRlciIsIlByb21pc2VSb3V0ZXIiLCJoYW5kbGVSZXF1ZXN0IiwiSU5WQUxJRF9KU09OIiwiYmFzZTY0IiwicHJvY2VzcyIsImVudiIsIlRFU1RJTkciLCJieXBhc3NBcHBTdG9yZVZhbGlkYXRpb24iLCJzdWNjZXNzQ2FsbGJhY2siLCJlcnJvckNhbGxiYWNrIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvUm91dGVycy9JQVBWYWxpZGF0aW9uUm91dGVyLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuY29uc3QgcmVxdWVzdCA9IHJlcXVpcmUoJy4uL3JlcXVlc3QnKTtcbmNvbnN0IHJlc3QgPSByZXF1aXJlKCcuLi9yZXN0Jyk7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbi8vIFRPRE8gbW92ZSB2YWxpZGF0aW9uIGxvZ2ljIGluIElBUFZhbGlkYXRpb25Db250cm9sbGVyXG5jb25zdCBJQVBfU0FOREJPWF9VUkwgPSAnaHR0cHM6Ly9zYW5kYm94Lml0dW5lcy5hcHBsZS5jb20vdmVyaWZ5UmVjZWlwdCc7XG5jb25zdCBJQVBfUFJPRFVDVElPTl9VUkwgPSAnaHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS92ZXJpZnlSZWNlaXB0JztcblxuY29uc3QgQVBQX1NUT1JFX0VSUk9SUyA9IHtcbiAgMjEwMDA6ICdUaGUgQXBwIFN0b3JlIGNvdWxkIG5vdCByZWFkIHRoZSBKU09OIG9iamVjdCB5b3UgcHJvdmlkZWQuJyxcbiAgMjEwMDI6ICdUaGUgZGF0YSBpbiB0aGUgcmVjZWlwdC1kYXRhIHByb3BlcnR5IHdhcyBtYWxmb3JtZWQgb3IgbWlzc2luZy4nLFxuICAyMTAwMzogJ1RoZSByZWNlaXB0IGNvdWxkIG5vdCBiZSBhdXRoZW50aWNhdGVkLicsXG4gIDIxMDA0OiAnVGhlIHNoYXJlZCBzZWNyZXQgeW91IHByb3ZpZGVkIGRvZXMgbm90IG1hdGNoIHRoZSBzaGFyZWQgc2VjcmV0IG9uIGZpbGUgZm9yIHlvdXIgYWNjb3VudC4nLFxuICAyMTAwNTogJ1RoZSByZWNlaXB0IHNlcnZlciBpcyBub3QgY3VycmVudGx5IGF2YWlsYWJsZS4nLFxuICAyMTAwNjogJ1RoaXMgcmVjZWlwdCBpcyB2YWxpZCBidXQgdGhlIHN1YnNjcmlwdGlvbiBoYXMgZXhwaXJlZC4nLFxuICAyMTAwNzogJ1RoaXMgcmVjZWlwdCBpcyBmcm9tIHRoZSB0ZXN0IGVudmlyb25tZW50LCBidXQgaXQgd2FzIHNlbnQgdG8gdGhlIHByb2R1Y3Rpb24gZW52aXJvbm1lbnQgZm9yIHZlcmlmaWNhdGlvbi4gU2VuZCBpdCB0byB0aGUgdGVzdCBlbnZpcm9ubWVudCBpbnN0ZWFkLicsXG4gIDIxMDA4OiAnVGhpcyByZWNlaXB0IGlzIGZyb20gdGhlIHByb2R1Y3Rpb24gZW52aXJvbm1lbnQsIGJ1dCBpdCB3YXMgc2VudCB0byB0aGUgdGVzdCBlbnZpcm9ubWVudCBmb3IgdmVyaWZpY2F0aW9uLiBTZW5kIGl0IHRvIHRoZSBwcm9kdWN0aW9uIGVudmlyb25tZW50IGluc3RlYWQuJyxcbn07XG5cbmZ1bmN0aW9uIGFwcFN0b3JlRXJyb3Ioc3RhdHVzKSB7XG4gIHN0YXR1cyA9IHBhcnNlSW50KHN0YXR1cyk7XG4gIHZhciBlcnJvclN0cmluZyA9IEFQUF9TVE9SRV9FUlJPUlNbc3RhdHVzXSB8fCAndW5rbm93biBlcnJvci4nO1xuICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cywgZXJyb3I6IGVycm9yU3RyaW5nIH07XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlV2l0aEFwcFN0b3JlKHVybCwgcmVjZWlwdCkge1xuICByZXR1cm4gcmVxdWVzdCh7XG4gICAgdXJsOiB1cmwsXG4gICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgYm9keTogeyAncmVjZWlwdC1kYXRhJzogcmVjZWlwdCB9LFxuICAgIGhlYWRlcnM6IHtcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgfSxcbiAgfSkudGhlbihodHRwUmVzcG9uc2UgPT4ge1xuICAgIGNvbnN0IGJvZHkgPSBodHRwUmVzcG9uc2UuZGF0YTtcbiAgICBpZiAoYm9keSAmJiBib2R5LnN0YXR1cyA9PT0gMCkge1xuICAgICAgLy8gTm8gbmVlZCB0byBwYXNzIGFueXRoaW5nLCBzdGF0dXMgaXMgT0tcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gcmVjZWlwdCBpcyBmcm9tIHRlc3QgYW5kIHNob3VsZCBnbyB0byB0ZXN0XG4gICAgdGhyb3cgYm9keTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVGb3JQcm9kdWN0SWRlbnRpZmllcihwcm9kdWN0SWRlbnRpZmllciwgcmVxKSB7XG4gIHJldHVybiByZXN0XG4gICAgLmZpbmQoXG4gICAgICByZXEuY29uZmlnLFxuICAgICAgcmVxLmF1dGgsXG4gICAgICAnX1Byb2R1Y3QnLFxuICAgICAgeyBwcm9kdWN0SWRlbnRpZmllcjogcHJvZHVjdElkZW50aWZpZXIgfSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICApXG4gICAgLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgY29uc3QgcHJvZHVjdHMgPSByZXN1bHQucmVzdWx0cztcbiAgICAgIGlmICghcHJvZHVjdHMgfHwgcHJvZHVjdHMubGVuZ3RoICE9IDEpIHtcbiAgICAgICAgLy8gRXJyb3Igbm90IGZvdW5kIG9yIHRvbyBtYW55XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZC4nKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGRvd25sb2FkID0gcHJvZHVjdHNbMF0uZG93bmxvYWQ7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHsgcmVzcG9uc2U6IGRvd25sb2FkIH0pO1xuICAgIH0pO1xufVxuXG5leHBvcnQgY2xhc3MgSUFQVmFsaWRhdGlvblJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBoYW5kbGVSZXF1ZXN0KHJlcSkge1xuICAgIGxldCByZWNlaXB0ID0gcmVxLmJvZHkucmVjZWlwdDtcbiAgICBjb25zdCBwcm9kdWN0SWRlbnRpZmllciA9IHJlcS5ib2R5LnByb2R1Y3RJZGVudGlmaWVyO1xuXG4gICAgaWYgKCFyZWNlaXB0IHx8ICFwcm9kdWN0SWRlbnRpZmllcikge1xuICAgICAgLy8gVE9ETzogRXJyb3IsIG1hbGZvcm1lZCByZXF1ZXN0XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnbWlzc2luZyByZWNlaXB0IG9yIHByb2R1Y3RJZGVudGlmaWVyJyk7XG4gICAgfVxuXG4gICAgLy8gVHJhbnNmb3JtIHRoZSBvYmplY3QgaWYgdGhlcmVcbiAgICAvLyBvdGhlcndpc2UgYXNzdW1lIGl0J3MgaW4gQmFzZTY0IGFscmVhZHlcbiAgICBpZiAodHlwZW9mIHJlY2VpcHQgPT0gJ29iamVjdCcpIHtcbiAgICAgIGlmIChyZWNlaXB0WydfX3R5cGUnXSA9PSAnQnl0ZXMnKSB7XG4gICAgICAgIHJlY2VpcHQgPSByZWNlaXB0LmJhc2U2NDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuVEVTVElORyA9PSAnMScgJiYgcmVxLmJvZHkuYnlwYXNzQXBwU3RvcmVWYWxpZGF0aW9uKSB7XG4gICAgICByZXR1cm4gZ2V0RmlsZUZvclByb2R1Y3RJZGVudGlmaWVyKHByb2R1Y3RJZGVudGlmaWVyLCByZXEpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN1Y2Nlc3NDYWxsYmFjaygpIHtcbiAgICAgIHJldHVybiBnZXRGaWxlRm9yUHJvZHVjdElkZW50aWZpZXIocHJvZHVjdElkZW50aWZpZXIsIHJlcSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXJyb3JDYWxsYmFjayhlcnJvcikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiBhcHBTdG9yZUVycm9yKGVycm9yLnN0YXR1cykgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbGlkYXRlV2l0aEFwcFN0b3JlKElBUF9QUk9EVUNUSU9OX1VSTCwgcmVjZWlwdCkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHN1Y2Nlc3NDYWxsYmFjaygpO1xuICAgICAgfSxcbiAgICAgIGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLnN0YXR1cyA9PSAyMTAwNykge1xuICAgICAgICAgIHJldHVybiB2YWxpZGF0ZVdpdGhBcHBTdG9yZShJQVBfU0FOREJPWF9VUkwsIHJlY2VpcHQpLnRoZW4oXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBzdWNjZXNzQ2FsbGJhY2soKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBlcnJvckNhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy92YWxpZGF0ZV9wdXJjaGFzZScsIHRoaXMuaGFuZGxlUmVxdWVzdCk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBQUEsY0FBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBR0EsSUFBQUMsS0FBQSxHQUFBRixzQkFBQSxDQUFBQyxPQUFBO0FBQStCLFNBQUFELHVCQUFBRyxDQUFBLFdBQUFBLENBQUEsSUFBQUEsQ0FBQSxDQUFBQyxVQUFBLEdBQUFELENBQUEsS0FBQUUsT0FBQSxFQUFBRixDQUFBO0FBRi9CLE1BQU1HLE9BQU8sR0FBR0wsT0FBTyxDQUFDLFlBQVksQ0FBQztBQUNyQyxNQUFNTSxJQUFJLEdBQUdOLE9BQU8sQ0FBQyxTQUFTLENBQUM7QUFHL0I7QUFDQSxNQUFNTyxlQUFlLEdBQUcsZ0RBQWdEO0FBQ3hFLE1BQU1DLGtCQUFrQixHQUFHLDRDQUE0QztBQUV2RSxNQUFNQyxnQkFBZ0IsR0FBRztFQUN2QixLQUFLLEVBQUUsNERBQTREO0VBQ25FLEtBQUssRUFBRSxpRUFBaUU7RUFDeEUsS0FBSyxFQUFFLHlDQUF5QztFQUNoRCxLQUFLLEVBQUUsMkZBQTJGO0VBQ2xHLEtBQUssRUFBRSxnREFBZ0Q7RUFDdkQsS0FBSyxFQUFFLHlEQUF5RDtFQUNoRSxLQUFLLEVBQUUscUpBQXFKO0VBQzVKLEtBQUss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
|