-
Notifications
You must be signed in to change notification settings - Fork 55
/
create_token.js
163 lines (152 loc) · 4.91 KB
/
create_token.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
require('dotenv').config();
const jwt = require('jsonwebtoken');
const fs = require('fs');
const inquirer = require('inquirer');
const fetch = require("node-fetch");
// Flags
// Set VALIDATE_TOKEN to false to skip the
// fetch request validation step and just
// generate the token ('offline mode')
const VALIDATE_TOKEN = true;
// Set SAVE_TO_FILE to false to simply
// log the output JWT to the console
const SAVE_TO_FILE = true;
const now = Math.floor((Date.now() / 1000));
const alg = 'ES256';
const headers = {
'alg': alg,
'kid': ''
}
// Exp is set to now + 6 months
// which is the max time allowed for a
// jwt to exist for the Apple Music API.
// Change 15777000 to something else
// if you want it to expires sooner.
const payload = {
'iss': '',
'exp': now + 15777000,
'iat': now
}
let privateKey;
let dataReady = false;
// You can configure your teamID and Key ID
// by adding a .env file to this directory
// and setting TEAM_ID and KEY_ID
// the pass your .p8 private key path in as an
// argument to `npm run generate`
if(process.argv.length >= 3 && process.env.TEAM_ID && process.env.KEY_ID){
if(process.argv.indexOf('--test') > -1){
console.log('Generating test token\n');
privateKey = fs.readFileSync('too-many-requests.p8');
headers.kid = 'CapExedKid';
payload.iss = 'CapExdTeam';
} else {
privateKey = fs.readFileSync(process.argv[2]);
payload.iss = process.env.TEAM_ID;
headers.kid = process.env.KEY_ID;
}
dataReady = true;
} else {
// Use inquirer to collect information from user via command line
// if nothing passed
inquirer
.prompt([
{
type: 'input',
message: 'Private key file name:',
name: 'privateKeyFilename',
},
{
type: 'input',
message: 'Key ID:',
name: 'kid',
},
{
type: 'input',
message: 'Team ID:',
name: 'teamID',
},
])
.then((response) => {
try {
privateKey = fs.readFileSync(response.privateKeyFilename);
} catch (error) {
console.error(error);
}
payload.iss = response.teamId;
headers.kid = response.kid;
dataReady = true;
})
.catch(error => {
console.error(error);
})
}
// Define writeToFile function
function writeToFile(fileName, data) {
fs.writeFile(fileName, data, (err) =>
err ? console.log(err) : console.log('JWT Saved!')
);
}
// JWT are formed formed like:
// jwt.sign(payload, secretOrPrivateKey, [options, callback])
if(dataReady) {
try {
jwt.sign(payload, privateKey, {header: headers}, async function(error, token) {
if(error){
console.error(error);
process.exit(1);
}
if(!VALIDATE_TOKEN){
SAVE_TO_FILE ? writeToFile('token.jwt', token) : console.log(token);
process.exit(0);
}
console.log("Testing token... \n")
// test generated token against Apple Music API...
let url = 'https://api.music.apple.com/v1/catalog/ca/genres';
if(process.argv.indexOf('--test') > -1){
url = 'https://api.music.apple.com/v1/test';
}
await fetch(url, {
headers: {
Authorization: `Bearer ${token}`
}
})
.then(response => {
// Catch test error and stop
if(response.status == 401){
console.log('401');
console.log('The generated token is unauthorized to access the Apple Music API');
process.exit(1);
} else if(response.status == 429) {
if(process.argv.indexOf('--test') > -1){
console.log('✅ Test passed');
process.exit(0);
} else {
console.log('The generated token was rejected by the Apple Music API.');
console.log(`Status: ${response.status} Message: ${response.statusText}`);
process.exit(1);
}
}
return response.json();
})
.then(json => {
if(json) {
console.log('✅ Test passed');
} else {
console.log('❌ Test failed');
console.log('The JWT was generated but there was an error when it was presented ')
}
// Save the generated to token to a jwt file in the current directory
// or log to console.
SAVE_TO_FILE ? writeToFile('token.jwt', token) : console.log(token);
})
.catch(error => {
console.error(error);
})
});
} catch(error) {
console.error(error);
}
} else {
console.error("😬 The data was not properly processed to create a JWT.");
}