From a9c259d1be8bbc143439711413b3cfa4fffabc11 Mon Sep 17 00:00:00 2001 From: n4bb12 Date: Thu, 30 Jul 2020 00:56:09 +0200 Subject: [PATCH] Ensure the CLI is called back in the access-denied and error case --- src/cli/index.ts | 30 +++++++++++++++++++++++++++--- src/constants.ts | 4 ++++ src/server/flows/CliFlow.ts | 26 ++++++++++++++++++++------ 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/cli/index.ts b/src/cli/index.ts index e2071c68..4355b4c0 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -1,7 +1,17 @@ import express from "express" import open from "open" -import { buildStatusPage } from "../statusPage" +import { + cliDeniedCallbackPath, + cliErrorCallbackPath, + cliPort, + cliSuccessCallbackPath, +} from "../constants" +import { + accessDeniedPage, + buildErrorPage, + buildStatusPage, +} from "../statusPage" import { getConfigFile, getRegistry, save } from "./npm" import { printUsage } from "./usage" @@ -22,7 +32,7 @@ const successPage = buildStatusPage(` `) const server = express() - .get("/", (req, res) => { + .get(cliSuccessCallbackPath, (req, res) => { const token = decodeURIComponent(req.query.token as string) save(registry, token) res.setHeader("Content-Type", "text/html") @@ -30,4 +40,18 @@ const server = express() server.close() process.exit(0) }) - .listen(8239) + .get(cliDeniedCallbackPath, (req, res) => { + res.setHeader("Content-Type", "text/html") + res.status(401) + res.send(accessDeniedPage) + server.close() + process.exit(1) + }) + .get(cliErrorCallbackPath, (req, res) => { + res.setHeader("Content-Type", "text/html") + res.status(500) + res.send(buildErrorPage(req.query.message)) + server.close() + process.exit(1) + }) + .listen(cliPort) diff --git a/src/constants.ts b/src/constants.ts index d4531517..ae4ac5fa 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -3,3 +3,7 @@ export const publicRoot = __dirname + "/public" export const staticPath = "/-/static/" + pluginName export const authorizePath = "/-/oauth/authorize" export const callbackPath = "/-/oauth/callback" +export const cliSuccessCallbackPath = "/success" +export const cliDeniedCallbackPath = "/denied" +export const cliErrorCallbackPath = "/error" +export const cliPort = 8239 diff --git a/src/server/flows/CliFlow.ts b/src/server/flows/CliFlow.ts index aafeaccc..e61e7879 100644 --- a/src/server/flows/CliFlow.ts +++ b/src/server/flows/CliFlow.ts @@ -1,14 +1,21 @@ import { IPluginMiddleware } from "@verdaccio/types" import { Application, Handler } from "express" +import qs from "query-string" +import { + cliDeniedCallbackPath, + cliErrorCallbackPath, + cliPort, + cliSuccessCallbackPath, +} from "../../constants" import { logger } from "../../logger" import { AuthCore } from "../plugin/AuthCore" import { AuthProvider } from "../plugin/AuthProvider" import { Verdaccio } from "../verdaccio" -import { accessDeniedPage, WebFlow } from "./WebFlow" +import { WebFlow } from "./WebFlow" const cliAuthorizeUrl = "/oauth/authorize" -const cliCallbackUrl = "http://localhost:8239?token=" +const cliCallbackUrl = `http://localhost:${cliPort}` const providerId = "cli" const pluginAuthorizeUrl = WebFlow.getAuthorizePath(providerId) @@ -34,6 +41,8 @@ export class CliFlow implements IPluginMiddleware { } callback: Handler = async (req, res, next) => { + let redirectUrl: string + try { const code = await this.provider.getCode(req) const token = await this.provider.getToken(code) @@ -43,15 +52,20 @@ export class CliFlow implements IPluginMiddleware { if (this.core.authenticate(username, groups)) { const user = this.core.createAuthenticatedUser(username) const npmToken = await this.verdaccio.issueNpmToken(token, user) - const cli = cliCallbackUrl + encodeURIComponent(npmToken) + const params = qs.stringify({ token: npmToken }) - res.redirect(cli) + redirectUrl = cliCallbackUrl + cliSuccessCallbackPath + "?" + params } else { - res.status(401).send(accessDeniedPage) + redirectUrl = cliCallbackUrl + cliDeniedCallbackPath } } catch (error) { logger.error(error) - next(error) + + const params = qs.stringify({ message: error.message || error }) + + redirectUrl = cliCallbackUrl + cliErrorCallbackPath + "?" + params } + + res.redirect(redirectUrl) } }