@rage-against-the-pixel/app-store-connect-api 3.7.0 → 3.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # app-store-connect-api
2
2
 
3
+ [![Discord](https://img.shields.io/discord/855294214065487932.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/xQgMW9ufN4) [![NPM Version](https://img.shields.io/npm/v/%40rage-against-the-pixel%2Fapp-store-connect-api)](https://www.npmjs.com/package/@rage-against-the-pixel/app-store-connect-api) [![NPM Downloads](https://img.shields.io/npm/dw/%40rage-against-the-pixel%2Fapp-store-connect-api)](https://www.npmjs.com/package/@rage-against-the-pixel/app-store-connect-api)
4
+
3
5
  A TypeScript package for communicating with Apple [App Store Connect API](https://developer.apple.com/documentation/appstoreconnectapi)
4
6
 
5
7
  - Automatically generated API client using the latest [OpenAPI specification](https://developer.apple.com/sample-code/app-store-connect/app-store-connect-openapi-specification.zip) from Apple.
@@ -20,6 +22,9 @@ Download and save the private key `.p8` file to a save, secure location.
20
22
  The contents of this file is your `privateKey`.
21
23
  The `privateKeyId` and `issuerId` are both listed on the same page where you create your private key.
22
24
 
25
+ > [!NOTE]
26
+ > Individual keys do not require `issuerId`.
27
+
23
28
  ## Example
24
29
 
25
30
  ```ts
package/dist/client.d.ts CHANGED
@@ -41,5 +41,10 @@ declare class AppStoreConnectClient {
41
41
  * @see https://developer.apple.com/documentation/appstoreconnectapi/generating_tokens_for_api_requests
42
42
  */
43
43
  private generateAuthToken;
44
+ /**
45
+ * Generates a user auth token for authenticating with the App Store Connect API.
46
+ * @see https://developer.apple.com/documentation/appstoreconnectapi/generating-tokens-for-api-requests#Create-the-JWT-Payload-for-Individual-Keys
47
+ */
48
+ private generateUserAuthToken;
44
49
  }
45
50
  export { AppStoreConnectOptions, AppStoreConnectClient };
package/dist/client.js CHANGED
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
37
  };
@@ -51,14 +61,13 @@ class AppStoreConnectClient {
51
61
  this.bearerToken = this.appStoreConnectOptions.bearerToken;
52
62
  }
53
63
  else {
54
- if (this.appStoreConnectOptions.privateKeyId &&
55
- this.appStoreConnectOptions.issuerId &&
56
- (this.appStoreConnectOptions.privateKey || this.appStoreConnectOptions.privateKeyFile)) {
64
+ const { privateKeyId, issuerId, privateKey, privateKeyFile, expirationTime } = this.appStoreConnectOptions;
65
+ if (privateKeyId && (privateKey || privateKeyFile)) {
57
66
  const defaultExpirationTime = 600; // 10 minutes
58
- const expirationTime = this.appStoreConnectOptions.expirationTime ?? defaultExpirationTime;
59
- if (!this.bearerToken || this.bearerTokenGeneratedAt + expirationTime * 1000 < Date.now()) {
60
- if (this.appStoreConnectOptions.privateKeyFile) {
61
- const fileHandle = await fs_1.default.promises.open(this.appStoreConnectOptions.privateKeyFile, 'r');
67
+ const tokenExpirationTime = expirationTime ?? defaultExpirationTime;
68
+ if (!this.bearerToken || this.bearerTokenGeneratedAt + tokenExpirationTime * 1000 < Date.now()) {
69
+ if (privateKeyFile) {
70
+ const fileHandle = await fs_1.default.promises.open(privateKeyFile, fs_1.default.constants.O_RDONLY);
62
71
  try {
63
72
  this.appStoreConnectOptions.privateKey = await fileHandle.readFile('utf8');
64
73
  }
@@ -66,7 +75,13 @@ class AppStoreConnectClient {
66
75
  await fileHandle.close();
67
76
  }
68
77
  }
69
- this.bearerToken = await this.generateAuthToken(this.appStoreConnectOptions.issuerId, this.appStoreConnectOptions.privateKeyId, this.appStoreConnectOptions.privateKey, expirationTime);
78
+ if (issuerId) {
79
+ this.bearerToken = await this.generateAuthToken(issuerId, privateKeyId, this.appStoreConnectOptions.privateKey, tokenExpirationTime);
80
+ }
81
+ else {
82
+ this.bearerToken = await this.generateUserAuthToken(privateKeyId, this.appStoreConnectOptions.privateKey, tokenExpirationTime);
83
+ }
84
+ this.bearerTokenGeneratedAt = Date.now();
70
85
  }
71
86
  }
72
87
  else {
@@ -80,12 +95,27 @@ class AppStoreConnectClient {
80
95
  * @see https://developer.apple.com/documentation/appstoreconnectapi/generating_tokens_for_api_requests
81
96
  */
82
97
  async generateAuthToken(issuerId, privateKeyId, privateKey, expirationTime) {
83
- const alg = "ES256";
98
+ const alg = 'ES256';
84
99
  const key = await jose.importPKCS8(privateKey, alg);
85
100
  const token = await new jose.SignJWT({})
86
- .setProtectedHeader({ alg, kid: privateKeyId, typ: "JWT" })
101
+ .setProtectedHeader({ alg, kid: privateKeyId, typ: 'JWT' })
87
102
  .setIssuer(issuerId)
88
- .setAudience("appstoreconnect-v1")
103
+ .setAudience('appstoreconnect-v1')
104
+ .setExpirationTime(new Date(Date.now() + expirationTime * 1000))
105
+ .sign(key);
106
+ return token;
107
+ }
108
+ /**
109
+ * Generates a user auth token for authenticating with the App Store Connect API.
110
+ * @see https://developer.apple.com/documentation/appstoreconnectapi/generating-tokens-for-api-requests#Create-the-JWT-Payload-for-Individual-Keys
111
+ */
112
+ async generateUserAuthToken(privateKeyId, privateKey, expirationTime) {
113
+ const alg = 'ES256';
114
+ const key = await jose.importPKCS8(privateKey, alg);
115
+ const token = await new jose.SignJWT({})
116
+ .setProtectedHeader({ alg, kid: privateKeyId, typ: 'JWT' })
117
+ .setSubject('user')
118
+ .setAudience('appstoreconnect-v1')
89
119
  .setExpirationTime(new Date(Date.now() + expirationTime * 1000))
90
120
  .sign(key);
91
121
  return token;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rage-against-the-pixel/app-store-connect-api",
3
- "version": "3.7.0",
3
+ "version": "3.7.1",
4
4
  "description": "A TypeScript package for communicating with Apple App Store Connect API",
5
5
  "author": "RageAgainstThePixel",
6
6
  "license": "MIT",
@@ -46,4 +46,4 @@
46
46
  "@hey-api/client-fetch": "^0.4.1",
47
47
  "jose": "^5.9.4"
48
48
  }
49
- }
49
+ }