(input: {
readonly issuerBaseUrl: string;
readonly clientId: string;
readonly clientSecret: string;
})
| 101 | * the profile leaves "where the identity assertion comes from" to the host, |
| 102 | * and executor is handed the result on the connect request. */ |
| 103 | const singleSignOn = (input: { |
| 104 | readonly issuerBaseUrl: string; |
| 105 | readonly clientId: string; |
| 106 | readonly clientSecret: string; |
| 107 | }) => |
| 108 | Effect.promise(async (): Promise<string> => { |
| 109 | const authorize = await fetch( |
| 110 | `${input.issuerBaseUrl}/oauth2/${OKTA_AUTH_SERVER}/v1/authorize/callback`, |
| 111 | { |
| 112 | method: "POST", |
| 113 | headers: { "content-type": "application/x-www-form-urlencoded" }, |
| 114 | redirect: "manual", |
| 115 | body: new URLSearchParams({ |
| 116 | user_ref: OKTA_USER, |
| 117 | redirect_uri: SSO_REDIRECT_URI, |
| 118 | scope: "openid profile email", |
| 119 | client_id: input.clientId, |
| 120 | response_mode: "query", |
| 121 | auth_server_id: OKTA_AUTH_SERVER, |
| 122 | }), |
| 123 | }, |
| 124 | ); |
| 125 | if (authorize.status !== 302) { |
| 126 | throw new Error(`IdP authorize answered ${authorize.status}, expected a 302`); |
| 127 | } |
| 128 | const location = requireString(authorize.headers.get("location"), "authorize redirect"); |
| 129 | const code = requireString(new URL(location).searchParams.get("code"), "authorization code"); |
| 130 | |
| 131 | const token = await fetch(`${input.issuerBaseUrl}/oauth2/${OKTA_AUTH_SERVER}/v1/token`, { |
| 132 | method: "POST", |
| 133 | headers: { "content-type": "application/x-www-form-urlencoded" }, |
| 134 | body: new URLSearchParams({ |
| 135 | grant_type: "authorization_code", |
| 136 | code, |
| 137 | redirect_uri: SSO_REDIRECT_URI, |
| 138 | client_id: input.clientId, |
| 139 | client_secret: input.clientSecret, |
| 140 | }), |
| 141 | }); |
| 142 | if (!token.ok) throw new Error(`IdP token endpoint answered ${token.status}`); |
| 143 | const body = (await token.json()) as { readonly id_token?: string }; |
| 144 | return requireString(body.id_token, "id_token"); |
| 145 | }); |
| 146 | |
| 147 | const ledger = (instance: Emulator) => Effect.promise(() => instance.ledger.list()); |
| 148 |
no test coverage detected