Skip to content

Commit

Permalink
WIP using dashboard JWT tokens for tokens.
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinstubbs committed Aug 19, 2024
1 parent bf30f6a commit b1e8272
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 81 deletions.
95 changes: 90 additions & 5 deletions packages/cli/src/cli/commands/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ import http from "http";
import { dirname, join } from "path";
import url, { fileURLToPath } from "url";
import { parseJwt } from "@pantheon-systems/pcc-sdk-core";
import { OAuth2Client } from "google-auth-library";
import { Credentials, OAuth2Client } from "google-auth-library";
import nunjucks from "nunjucks";
import open from "open";
import ora from "ora";
import destroyer from "server-destroy";
import AddOnApiHelper from "../../lib/addonApiHelper";
import { getApiConfig } from "../../lib/apiConfig";
import {
CREDENTIAL_TYPE,
getLocalAuthDetails,
NextJwtCredentials,
persistAuthDetails,
} from "../../lib/localStorage";
import { errorHandler } from "../exceptions";
Expand All @@ -20,13 +22,17 @@ nunjucks.configure({ autoescape: true });

const OAUTH_SCOPES = ["https://www.googleapis.com/auth/userinfo.email"];

function login(extraScopes: string[]): Promise<void> {
export function loginOAuth(extraScopes: string[]): Promise<void> {
return new Promise(
// eslint-disable-next-line no-async-promise-executor -- Handling promise rejection in the executor
async (resolve, reject) => {
const spinner = ora("Logging you in...").start();
try {
const authData = await getLocalAuthDetails(extraScopes);
const authData = (await getLocalAuthDetails(
CREDENTIAL_TYPE.OAUTH,
extraScopes,
)) as Credentials | null;

if (authData) {
const scopes = authData.scope?.split(" ");

Expand Down Expand Up @@ -70,7 +76,7 @@ function login(extraScopes: string[]): Promise<void> {
);
const credentials = await AddOnApiHelper.getToken(code as string);
const jwtPayload = parseJwt(credentials.id_token as string);
await persistAuthDetails(credentials);
await persistAuthDetails(credentials, CREDENTIAL_TYPE.OAUTH);

res.end(
nunjucks.renderString(content.toString(), {
Expand Down Expand Up @@ -102,7 +108,86 @@ function login(extraScopes: string[]): Promise<void> {
},
);
}
export default errorHandler<string[]>(login);

function login(): Promise<void> {
return new Promise(
// eslint-disable-next-line no-async-promise-executor -- Handling promise rejection in the executor
async (resolve, reject) => {
const spinner = ora("Logging you in...").start();
try {
const authData = (await getLocalAuthDetails(
CREDENTIAL_TYPE.NEXT_JWT,
)) as NextJwtCredentials | null;
if (authData) {
console.log("already exists", { authData });
// spinner.succeed(
// `You are already logged in as ${authData.email}.`,
// );
// return resolve();
}

const server = http.createServer(async (req, res) => {
try {
if (!req.url) {
throw new Error("No URL path provided");
}

if (req.url.indexOf("/auth-success") !== -1) {
const qs = new url.URL(req.url, "http://localhost:3030")
.searchParams;
const token = qs.get("code") as string;
const email = qs.get("email") as string;
const expiration = qs.get("expiration") as string;
const currDir = dirname(fileURLToPath(import.meta.url));
const content = readFileSync(
join(currDir, "../templates/loginSuccess.html"),
);

await persistAuthDetails(
{
token,
email,
expiration,
},
CREDENTIAL_TYPE.NEXT_JWT,
);

res.end(
nunjucks.renderString(content.toString(), {
email: email,
}),
);
server.destroy();

spinner.succeed(`You are successfully logged in as ${email}`);
resolve();
} else {
res.writeHead(200, { "Content-Type": "text/plain" });
res.end("Hello World\n");
return;
}
} catch (e) {
spinner.fail();
reject(e);
}
});

destroyer(server);

server.listen(3030, () => {
// const apiConfig = await getApiConfig();
open("http://localhost:3000/auth/cli", { wait: true }).then((cp) =>
cp.kill(),
);
});
} catch (e) {
spinner.fail();
reject(e);
}
},
);
}
export default errorHandler<void>(login);
export const LOGIN_EXAMPLES = [
{ description: "Login the user", command: "$0 login" },
];
7 changes: 5 additions & 2 deletions packages/cli/src/cli/commands/logout.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { existsSync, rmSync } from "fs";
import ora from "ora";
import { AUTH_FILE_PATH } from "../../lib/localStorage";
import { AUTH_FOLDER_PATH } from "../../lib/localStorage";
import { errorHandler } from "../exceptions";

const logout = async () => {
const spinner = ora("Logging you out...").start();
try {
if (existsSync(AUTH_FILE_PATH)) rmSync(AUTH_FILE_PATH);
if (existsSync(AUTH_FOLDER_PATH))
rmSync(AUTH_FOLDER_PATH, {
recursive: true,
});
spinner.succeed("Successfully logged you out from PPC client!");
} catch (e) {
spinner.fail();
Expand Down
31 changes: 27 additions & 4 deletions packages/cli/src/cli/commands/whoAmI.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,39 @@
import { parseJwt } from "@pantheon-systems/pcc-sdk-core";
import chalk from "chalk";
import { getLocalAuthDetails } from "../../lib/localStorage";
import { Credentials } from "google-auth-library";
import {
CREDENTIAL_TYPE,
getLocalAuthDetails,
NextJwtCredentials,
} from "../../lib/localStorage";
import { errorHandler } from "../exceptions";

const printWhoAmI = async () => {
try {
const authData = await getLocalAuthDetails();
if (!authData) {
const nextJwt = (await getLocalAuthDetails(
CREDENTIAL_TYPE.NEXT_JWT,
)) as NextJwtCredentials | null;
if (!nextJwt) {
console.log("You aren't logged in.");
} else {
console.log(`You're logged in as ${nextJwt.email}`);
}
} catch (e) {
chalk.red("Something went wrong - couldn't retrieve auth info.");
throw e;
}

try {
const authData = (await getLocalAuthDetails(
CREDENTIAL_TYPE.OAUTH,
)) as Credentials | null;
if (!authData) {
console.log(
"You aren't logged into oauth. For some actions, the oauth connection isn't necessary. If you run a command that requires it, you will be only prompted to log in with oauth at that point.",
);
} else {
const jwtPayload = parseJwt(authData.id_token as string);
console.log(`You're logged in as ${jwtPayload.email}`);
console.log(`Oauth: You're logged in as ${jwtPayload.email}`);
}
} catch (e) {
chalk.red("Something went wrong - couldn't retrieve auth info.");
Expand Down
Loading

0 comments on commit b1e8272

Please sign in to comment.