UNPKG

4.08 kBJavaScriptView Raw
1/***************************************************************************************
2 * (c) 2017 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 ****************************************************************************************/
12
13const fs = require('fs');
14const inquirer = require('inquirer');
15const logVerboseHeader = require('./logVerboseHeader');
16const auth = require('@adobe/jwt-auth');
17
18const METASCOPES = [
19 'ent_reactor_sdk',
20 // The below metascopes are necessary to maintain for integrations created before the ent_reactor_sdk metascope existed.
21 'ent_reactor_extension_developer_sdk',
22 'ent_reactor_admin_sdk',
23];
24
25module.exports = async (
26 envConfig,
27 { privateKey, orgId, techAccountId, apiKey, clientSecret, verbose }
28) => {
29 privateKey = privateKey || process.env[envConfig.privateKeyEnvVar];
30 clientSecret = clientSecret || process.env[envConfig.clientSecretEnvVar];
31
32 if (!privateKey) {
33 ({ privateKey } = await inquirer.prompt([
34 {
35 type: 'input',
36 name: 'privateKey',
37 message: 'What is the path (relative or absolute) to your private key?',
38 validate: Boolean,
39 },
40 ]));
41 }
42
43 if (!orgId) {
44 ({ orgId } = await inquirer.prompt([
45 {
46 type: 'input',
47 name: 'orgId',
48 message: 'What is your organization ID?',
49 validate: Boolean,
50 },
51 ]));
52 }
53
54 if (!techAccountId) {
55 ({ techAccountId } = await inquirer.prompt([
56 {
57 type: 'input',
58 name: 'techAccountId',
59 message: 'What is your technical account ID?',
60 validate: Boolean,
61 },
62 ]));
63 }
64
65 if (!apiKey) {
66 ({ apiKey } = await inquirer.prompt([
67 {
68 type: 'input',
69 name: 'apiKey',
70 message: 'What is your API key/Client ID?',
71 validate: Boolean,
72 },
73 ]));
74 }
75
76 if (!clientSecret) {
77 ({ clientSecret } = await inquirer.prompt([
78 {
79 type: 'input',
80 name: 'clientSecret',
81 message: 'What is your client secret?',
82 validate: Boolean,
83 },
84 ]));
85 }
86
87 const privateKeyContent = fs.readFileSync(privateKey);
88
89 // The technical account could be configured with one of these metascopes (sometimes called roles).
90 // We have to try each one until we find the metascope that the account is using
91 // because apparently there's no API to figure out which metascope the account is using beforehand.
92 // If the account isn't configured for one of these metascopes, retrieving an access token
93 // will rightfully fail.
94 for (let i = 0; i < METASCOPES.length; i++) {
95 const metascope = METASCOPES[i];
96
97 if (verbose) {
98 logVerboseHeader(`Authenticating with metascope ${metascope}`);
99 }
100
101 try {
102 const response = await auth({
103 clientId: apiKey,
104 technicalAccountId: techAccountId,
105 orgId,
106 clientSecret,
107 privateKey: privateKeyContent,
108 metaScopes: [`${envConfig.scope}${metascope}`],
109 ims: envConfig.ims,
110 });
111
112 return response.access_token;
113 } catch (e) {
114 const errorMessage = e.message || 'An unknown authentication error occurred.';
115 const isScopeError = errorMessage.toLowerCase().indexOf('invalid_scope') !== -1;
116 const hasCheckedFinalScope = i === METASCOPES.length - 1;
117
118 // throw immediately if we've encountered any error that isn't a scope error
119 if (!isScopeError || hasCheckedFinalScope) {
120 throw new Error(
121 `Error retrieving access token. ${errorMessage}`
122 );
123 }
124 }
125 }
126};