74 lines
2.9 KiB
JavaScript
74 lines
2.9 KiB
JavaScript
#!/bin/node
|
|
|
|
import { SignJWT } from "jose"
|
|
import { createPrivateKey } from "crypto"
|
|
|
|
if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
console.log(`
|
|
Creates a JWT from the components found at Apple.
|
|
By default, the JWT has a 6 months expiry date.
|
|
Read more: https://developer.apple.com/documentation/sign_in_with_apple/generate_and_validate_tokens#3262048
|
|
|
|
Usage:
|
|
node apple.mjs [--kid] [--iss] [--private_key] [--sub] [--expires_in] [--exp]
|
|
APPLE_ID=com.mwhitnessing.sofia
|
|
APPLE_TEAM_ID=XC57P9SXDK
|
|
APPLE_KEY_ID=TB3V355G5Y
|
|
APPLE_KEY=-----BEGIN PRIVATE KEY----- MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgL3WoWMr7zzqtZdF/wNEJ9+yMP2qNJV305gTdF+++hLOgCgYIKoZIzj0DAQehRANCAATqlUN+GE7/r8UQc93hRG9UxCtBcJEcgSGwYVPtZvA5igUBxY/6+RO/Tcnq9xT/6PZD0A82vMNSjoJ6/KyhaFLl -----END PRIVATE KEY-----
|
|
node setupAppleId.mjs --kid YOUR_KEY_ID --iss YOUR_TEAM_ID --private_key "$(cat key.p8)" --sub YOUR_CLIENT_ID --expires_in 15778800
|
|
|
|
node setupAppleId.mjs --kid TB3V355G5Y --iss XC57P9SXDK --sub com.mwhitnessing.sofia --private_key "-----BEGIN PRIVATE KEY----- MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgL3WoWMr7zzqtZdF/ wNEJ9+yMP2qNJV305gTdF+++hLOgCgYIKoZIzj0DAQehRANCAATqlUN+GE7/r8UQ c93hRG9UxCtBcJEcgSGwYVPtZvA5igUBxY/6+RO/Tcnq9xT/6PZD0A82vMNSjoJ6 /KyhaFLl -----END PRIVATE KEY-----"
|
|
|
|
|
|
Options:
|
|
--help Print this help message
|
|
--kid, --key_id The key id of the private key
|
|
--iss, --team_id The Apple team ID
|
|
--private_key The private key to use to sign the JWT. (Starts with -----BEGIN PRIVATE KEY-----)
|
|
--sub, --client_id The client id to use in the JWT.
|
|
--expires_in Number of seconds from now when the JWT should expire. Defaults to 6 months.
|
|
--exp Future date in seconds when the JWT expires
|
|
`)
|
|
} else {
|
|
const args = process.argv.slice(2).reduce((acc, arg, i) => {
|
|
if (arg.match(/^--\w/)) {
|
|
const key = arg.replace(/^--/, "").toLowerCase()
|
|
acc[key] = process.argv[i + 3]
|
|
}
|
|
return acc
|
|
}, {})
|
|
|
|
const {
|
|
team_id,
|
|
iss = team_id,
|
|
|
|
private_key,
|
|
|
|
client_id,
|
|
sub = client_id,
|
|
|
|
key_id,
|
|
kid = key_id,
|
|
|
|
expires_in = 86400 * 180,
|
|
exp = Math.ceil(Date.now() / 1000) + expires_in,
|
|
} = args
|
|
|
|
/**
|
|
* How long is the secret valid in seconds.
|
|
* @default 15780000
|
|
*/
|
|
const expiresAt = Math.ceil(Date.now() / 1000) + expires_in
|
|
const expirationTime = exp ?? expiresAt
|
|
console.log(`
|
|
Apple client secret generated. Valid until: ${new Date(expirationTime * 1000)}
|
|
|
|
${await new SignJWT({})
|
|
.setAudience("https://appleid.apple.com")
|
|
.setIssuer(iss)
|
|
.setIssuedAt()
|
|
.setExpirationTime(expirationTime)
|
|
.setSubject(sub)
|
|
.setProtectedHeader({ alg: "ES256", kid })
|
|
.sign(createPrivateKey(private_key.replace(/\\n/g, "\n")))}`)
|
|
} |