kinde-cli
Version:
Kinde cli for managing your business integration, users, roles and permissions etc
165 lines (164 loc) • 7.31 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const error_1 = require("../utils/error");
const prompts_1 = require("@clack/prompts");
const picocolors_1 = __importDefault(require("picocolors"));
const qs_1 = __importDefault(require("qs"));
const zod_1 = require("zod");
const axios_1 = require("../lib/axios");
const index_1 = require("../utils/index");
const storage_1 = require("../utils/storage");
const spinner = (0, prompts_1.spinner)();
const command = {
DOMAIN: {
identifier: "Domain",
desc: "Business domain eg: https://<domain>.kinde.com",
attr: "required",
},
CLIENTID: {
identifier: "ClientId",
desc: "From Settings > Applications > New Application",
attr: "required",
},
CLIENTSECRET: {
identifier: "ClientSecret",
desc: "From Settings > Applications > New Application",
attr: "required",
},
};
class Authentication {
constructor(program) {
this.program = program;
this.handleAuthentication();
}
handleAuthentication() {
let program = this.program;
program
.command("login")
.description(picocolors_1.default.blue("Obtain authentication to use this CLI. Requirements include the Business Domain Client Id and Client Secret. For more information, refer to: https://kinde.com/docs/build/get-access-token-for-connecting-securely-to-kindes-api/"))
.action((0, index_1.errorHandler)("NoAuth", (str, options) => __awaiter(this, void 0, void 0, function* () {
yield (0, storage_1.clearGlobalConfig)();
let data = yield this.__getAuthenticationPrompt();
yield this.generateAccessToken(data);
})));
}
__getAuthenticationPrompt() {
return __awaiter(this, void 0, void 0, function* () {
let values = yield (0, prompts_1.group)({
domain: () => (0, prompts_1.text)({
message: (0, index_1.generateMessage)({
identifier: command.DOMAIN.identifier,
desc: command.DOMAIN.desc,
attr: command.DOMAIN.attr,
}),
defaultValue: undefined,
validate(value) {
if (!value)
return "Business domain is required!!";
},
}),
clientId: () => (0, prompts_1.text)({
message: (0, index_1.generateMessage)({
identifier: command.CLIENTID.identifier,
desc: command.CLIENTID.desc,
attr: command.CLIENTID.attr,
}),
defaultValue: undefined,
validate(value) {
if (!value)
return "Client Id is required!!";
},
}),
clientSecret: () => (0, prompts_1.text)({
message: (0, index_1.generateMessage)({
identifier: command.CLIENTSECRET.identifier,
desc: command.CLIENTSECRET.desc,
attr: command.CLIENTSECRET.attr,
}),
defaultValue: undefined,
validate(value) {
if (!value)
return "Client Secret is required!!";
},
}),
}, index_1.onCancelCallback);
return values;
});
}
generateAccessToken(args) {
return __awaiter(this, void 0, void 0, function* () {
let { domain, clientId, clientSecret } = args;
let rawInput = zod_1.z.object({
clientId: zod_1.z.string().min(1),
clientSecret: zod_1.z.string().min(1),
domain: zod_1.z.string().url(),
});
let validation = rawInput.safeParse(args);
if (!validation.success) {
(0, error_1.prettifyZod)(validation);
throw new Error("Input Validation Error, please make sure you entered valid data");
}
let noApiEndingPath = (0, index_1.extractUrlWithoutApi)(domain);
if (!noApiEndingPath) {
throw new Error("Please provide a valid kinde domain, go to your dashboard > application to copy it");
}
// URL Encoded Params
let payload = qs_1.default.stringify({
grant_type: "client_credentials",
client_id: clientId,
client_secret: clientSecret,
audience: `${noApiEndingPath}/api`,
});
spinner.start("Authenticating, please wait...");
let accessTokenResponse = yield (0, axios_1.axiosRequest)({
path: `${noApiEndingPath}/oauth2/token`,
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Accept: "application/json",
},
data: payload,
});
if (accessTokenResponse.error) {
spinner.stop("Error authenticating user, please try again", accessTokenResponse.status);
(0, error_1.prettifyAxios)(accessTokenResponse);
return;
}
spinner.stop("Authentication success, please hold on...");
let configData = {
clientId,
clientSecret,
normalDomain: domain,
personalDomainNoApiEndingPath: `${noApiEndingPath}/api`,
token: accessTokenResponse.data,
};
spinner.start("Hold on creating directory...");
let rootPath = (0, storage_1.createRootDirectory)();
if (!rootPath) {
spinner.stop("Failed to create directory", 400);
return;
}
spinner.stop();
spinner.start("Hold on writing config to directory...");
let configCreated = yield (0, storage_1.writeGlobalConfig)(configData);
if (!configCreated) {
spinner.stop("Falled to write config to directory", 400);
return;
}
spinner.stop("Config was saved sucessfully...");
});
}
}
exports.default = Authentication;