From 316ba2f6b9eadb9402d7191b2fec2bee19cd6fcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrej=20Tokar=C4=8D=C3=ADk?= Date: Wed, 5 May 2021 03:03:49 +0200 Subject: [PATCH] Use dedicated API for app FQDN resolving (#284) (#298) --- .../src/AppLauncher/useAppLauncher.ts | 47 +++++++++++++------ packages/teleport/src/config.ts | 13 ++++- packages/teleport/src/services/apps/apps.ts | 20 ++++---- 3 files changed, 55 insertions(+), 25 deletions(-) diff --git a/packages/teleport/src/AppLauncher/useAppLauncher.ts b/packages/teleport/src/AppLauncher/useAppLauncher.ts index 78a947828..15c9fbe46 100644 --- a/packages/teleport/src/AppLauncher/useAppLauncher.ts +++ b/packages/teleport/src/AppLauncher/useAppLauncher.ts @@ -26,21 +26,9 @@ export default function useAppLauncher() { const { attempt, setAttempt } = useAttempt('processing'); React.useEffect(() => { - service - .createAppSession(params) - .then(result => { - // make a redirect to the requested app auth endpoint - const location = window.location; - const port = location.port ? ':' + location.port : ''; - const state = getUrlParameter('state', location.search); - const authUrl = `https://${result.fqdn}${port}/x-teleport-auth`; - if (state === '') { - const clusterId = params.clusterId ? params.clusterId : ''; - const publicAddr = params.publicAddr ? params.publicAddr : ''; - window.location.replace(`${authUrl}?cluster=${clusterId}&addr=${publicAddr}`); - } else { - window.location.replace(`${authUrl}?state=${state}#value=${result.value}`); - } + resolveRedirectUrl(params) + .then(url => { + window.location.replace(url); }) .catch((err: Error) => { setAttempt({ @@ -54,3 +42,32 @@ export default function useAppLauncher() { ...attempt, }; } + +function resolveRedirectUrl(params: UrlLauncherParams) { + const location = window.location; + const port = location.port ? ':' + location.port : ''; + const state = getUrlParameter('state', location.search); + + // no state value: let the target app know of a new auth exchange + if (!state) { + return service.getAppFqdn(params).then(result => { + const url = new URL(`https://${result.fqdn}${port}/x-teleport-auth`); + if (params.clusterId) { + url.searchParams.set('cluster', params.clusterId); + } + if (params.publicAddr) { + url.searchParams.set('addr', params.publicAddr); + } + + return url.toString(); + }); + } + + // state value received: create new session for the target app + return service.createAppSession(params).then(result => { + const url = new URL(`https://${result.fqdn}${port}/x-teleport-auth`); + url.searchParams.set('state', state); + url.hash = `#value=${result.value}`; + return url.toString(); + }); +} diff --git a/packages/teleport/src/config.ts b/packages/teleport/src/config.ts index 8c83e841d..48694b118 100644 --- a/packages/teleport/src/config.ts +++ b/packages/teleport/src/config.ts @@ -75,7 +75,8 @@ const cfg = { }, api: { - aapSession: '/v1/webapi/sessions/app', + appSession: '/v1/webapi/sessions/app', + appFqdnPath: '/v1/webapi/apps/:fqdn/:clusterId?/:publicAddr?', applicationsPath: '/v1/webapi/sites/:clusterId/apps', clustersPath: '/v1/webapi/sites', clusterEventsPath: `/v1/webapi/sites/:clusterId/events/search?from=:start?&to=:end?&limit=:limit?`, @@ -113,6 +114,10 @@ const cfg = { appNodeScriptPath: '/scripts/:token/install-app.sh?name=:name&uri=:uri', }, + getAppFqdnUrl(params: UrlAppParams) { + return generatePath(cfg.api.appFqdnPath, { ...params }); + }, + getClusterEventsUrl(clusterId: string, params: UrlClusterEventsParams) { return generatePath(cfg.api.clusterEventsPath, { clusterId, @@ -294,6 +299,12 @@ export interface UrlParams { serverId?: string; } +export interface UrlAppParams { + fqdn: string; + clusterId?: string; + publicAddr?: string; +} + export interface UrlScpParams { clusterId: string; serverId: string; diff --git a/packages/teleport/src/services/apps/apps.ts b/packages/teleport/src/services/apps/apps.ts index d50b5e397..172a748c4 100644 --- a/packages/teleport/src/services/apps/apps.ts +++ b/packages/teleport/src/services/apps/apps.ts @@ -16,7 +16,7 @@ import { map } from 'lodash'; import api from 'teleport/services/api'; -import cfg from 'teleport/config'; +import cfg, { UrlAppParams } from 'teleport/config'; import makeApp from './makeApps'; const service = { @@ -26,10 +26,10 @@ const service = { .then(json => map(json.items, makeApp)); }, - createAppSession(params: CreateAppSessionParams) { + createAppSession(params: UrlAppParams) { const { fqdn, clusterId = '', publicAddr = '' } = params; return api - .post(cfg.api.aapSession, { + .post(cfg.api.appSession, { fqdn, cluster_name: clusterId, public_addr: publicAddr, @@ -39,12 +39,14 @@ const service = { value: json.value as string, })); }, + + getAppFqdn(params: UrlAppParams) { + return api + .get(cfg.getAppFqdnUrl(params)) + .then(json => ({ + fqdn: json.fqdn as string, + })); + }, }; export default service; - -type CreateAppSessionParams = { - fqdn: string; - clusterId?: string; - publicAddr?: string; -};