diff --git a/e2e/apps/redirect-model/src/apps/orchestrators/createMessageComponent.tsx b/e2e/apps/redirect-model/src/apps/orchestrators/createMessageComponent.tsx index 32c11dc..4afdc5e 100644 --- a/e2e/apps/redirect-model/src/apps/orchestrators/createMessageComponent.tsx +++ b/e2e/apps/redirect-model/src/apps/orchestrators/createMessageComponent.tsx @@ -1,5 +1,8 @@ import { useEffect, useState } from 'react'; +import { MyAccountClient } from '@okta/auth-foundation/myaccount'; import { Credential, type FetchClient } from '@okta/spa-platform'; +import { oauthConfig } from '../../auth'; + // NOTE: This HOC-like pattern is just to make the test app less complex // The recommended way to do this in a real app is instantinating a singleton @@ -12,7 +15,10 @@ export function createMessageComponent (fetchClient: FetchClient) { const response = await fetchClient.fetch('/api/messages'); return response.json(); }; - + + // @ts-ignore + const myaccount = new MyAccountClient(oauthConfig.issuer, fetchClient.orchestrator); + return function Messages () { const [messages, setMessages] = useState([]); const [error, setError] = useState(false); @@ -36,6 +42,17 @@ export function createMessageComponent (fetchClient: FetchClient) { const handleClearCreds = async () => { Credential.clear(); }; + + const getProfile = async () => { + try { + const profile = await myaccount.getProfile(); + console.log('getProfile response: ', profile); + } + catch (err) { + console.log('getProfile failed'); + console.log(err); + } + } useEffect(() => { if (dataFetched) { @@ -52,6 +69,7 @@ export function createMessageComponent (fetchClient: FetchClient) {
+
{ error && (

Please login

) } { !error && messages.length < 1 && (
Loading...
) } diff --git a/e2e/apps/redirect-model/src/auth.tsx b/e2e/apps/redirect-model/src/auth.tsx index d40732b..330375f 100644 --- a/e2e/apps/redirect-model/src/auth.tsx +++ b/e2e/apps/redirect-model/src/auth.tsx @@ -7,11 +7,14 @@ const USE_DPOP = __USE_DPOP__ === "true"; const isOIDC = (new URL(window.location.href).searchParams.get('oidc') !== "false"); +// TODO: enable to test MyAccount API +// const customScopes = [ +// 'okta.myAccount.profile.read' +// ]; const customScopes = []; -// const customScopes = []; export const oauthConfig: any = { - issuer: __ISSUER__, + issuer: customScopes?.length ? `${__ISSUER__}/oauth2/default` : __ISSUER__, clientId: USE_DPOP ? __DPOP_CLIENT_ID__ : __SPA_CLIENT_ID__, scopes: [...(isOIDC ? ['openid', 'profile', 'email'] : []), 'offline_access', ...customScopes], dpop: USE_DPOP diff --git a/packages/auth-foundation/package.json b/packages/auth-foundation/package.json index 5bd6f41..370773e 100644 --- a/packages/auth-foundation/package.json +++ b/packages/auth-foundation/package.json @@ -30,6 +30,10 @@ "types": "./dist/types/internal.d.ts", "import": "./dist/esm/internal.js" }, + "./myaccount": { + "types": "./dist/types/MyAccountClient.d.ts", + "import": "./dist/esm/MyAccountClient.js" + }, "./package.json": "./package.json" }, "sideEffects": [ diff --git a/packages/auth-foundation/rollup.config.mjs b/packages/auth-foundation/rollup.config.mjs index 76c9f5e..2565fed 100644 --- a/packages/auth-foundation/rollup.config.mjs +++ b/packages/auth-foundation/rollup.config.mjs @@ -7,6 +7,6 @@ const base = baseConfig(ts, pkg); export default { ...base, - input: [base.input, 'src/client.ts', 'src/internal.ts'], + input: [base.input, 'src/client.ts', 'src/internal.ts', 'src/MyAccountClient.ts'], external: [...Object.keys(pkg.dependencies)], }; diff --git a/packages/auth-foundation/src/MyAccountClient.ts b/packages/auth-foundation/src/MyAccountClient.ts new file mode 100644 index 0000000..898225f --- /dev/null +++ b/packages/auth-foundation/src/MyAccountClient.ts @@ -0,0 +1,35 @@ +import { FetchClient } from './FetchClient'; +import { TokenOrchestrator } from './TokenOrchestrator'; + + +/** + * Under Construction + */ +export class MyAccountClient { + fetcher: FetchClient; + baseURL: URL; + + constructor (orgURL: URL | string, orchestrator: TokenOrchestrator) { + this.baseURL = new URL(orgURL); + this.fetcher = new FetchClient(orchestrator); + + // required to avoid 406 errors from API + this.fetcher.defaultHeaders = { Accept: 'application/json;okta-version=1.0' }; + } + + async makeRequest (path: string, init: Parameters[1] = {}) { + const url = new URL(`/idp/myaccount${path}`, this.baseURL); + const response = await this.fetcher.fetch(url, init); + + if (!response.ok) { + throw new Error('TODO') + } + + return await response.json(); + } + + // https://developer.okta.com/docs/api/openapi/okta-myaccount/myaccount/tag/Profile/ + async getProfile () { + return this.makeRequest('/profile', { scopes: ['okta.myAccount.profile.read'] }); + } +}