* Returns an existing authentication token (if its still valid) or generates a new one.
()
| 277 | * Returns an existing authentication token (if its still valid) or generates a new one. |
| 278 | */ |
| 279 | private async getToken(): Promise<string> { |
| 280 | // Reuse previously created token if it hasn't expired. |
| 281 | if (this.token && !this.tokenExpired) return this.token |
| 282 | |
| 283 | // Tokens must expire after at most 1 hour. |
| 284 | const now = new Date() |
| 285 | const expiry = new Date(now.getTime() + AppStoreServerAPI.maxTokenAge * 1000) |
| 286 | const expirySeconds = Math.floor(expiry.getTime() / 1000) |
| 287 | |
| 288 | const payload = { |
| 289 | bid: this.bundleId, |
| 290 | nonce: randomUUID() |
| 291 | } |
| 292 | |
| 293 | const privateKey = await this.key |
| 294 | |
| 295 | const jwt = await new jose.SignJWT(payload) |
| 296 | .setProtectedHeader({ alg: "ES256", kid: this.keyId, typ: "JWT" }) |
| 297 | .setIssuer(this.issuerId) |
| 298 | .setIssuedAt() |
| 299 | .setExpirationTime(expirySeconds) |
| 300 | .setAudience("appstoreconnect-v1") |
| 301 | .sign(privateKey) |
| 302 | |
| 303 | this.token = jwt |
| 304 | this.tokenExpiry = expiry |
| 305 | |
| 306 | return jwt |
| 307 | } |
| 308 | |
| 309 | /** |
| 310 | * Returns whether the previously generated token can still be used. |