Sandcastle oauth with ion#13403
Conversation
|
Thank you for the pull request, @jjspace! ✅ We can confirm we have a CLA on file for you. |
|
Thanks @jjspace!
|
ggetz
left a comment
There was a problem hiding this comment.
- Currently, this stops short of comprehensive error handling and communicating that status to the user. Any thoughts on how to address this?
- Can we put the OAuth credentials in an environment variable instead of hardcoded, like in
buildSandcastle.jsand the cite config?
| * @param {ImportList} options.imports Set of imports to add to the import map for the iframe and standalone html pages. These paths should match the URL where it can be accessed within the current environment. | ||
| * @param {string} options.outerOrigin Origin of the outer application | ||
| * @param {string} options.innerOrigin Origin of the inner viewer bucket. Defaults to the outerOrigin if not provided | ||
| * @param {{clientId: string, callbackUrl: string}} [options.ionClientSettings] Origin of the inner viewer bucket. Defaults to the outerOrigin if not provided |
There was a problem hiding this comment.
I think this is the wrong parameter desciption.
| response_type: "code", | ||
| scope: this.config.scopes.join(" "), | ||
| state: stateId, | ||
| }).toString()}`, |
There was a problem hiding this comment.
I believe the toString call is redundant when inside of a template string.
| async tokenExchange(code: string, state: UUID) { | ||
| // @see https://cesium.com/learn/ion/ion-oauth2/#step-3-token-exchange | ||
| // Retrieve the verifier based on the state | ||
| const { codeVerifier, previousPage } = (await getPkceState(state)) ?? {}; |
There was a problem hiding this comment.
Should this handle any errors thrown via a try/catch?
| this.oauth = | ||
| oauth ?? new IonOAuth({ ion, ionApi, callbackUrl, clientId, scopes }); | ||
| } |
There was a problem hiding this comment.
It's a bit non-obvious, when treating this class as a black box, that the parameters are either/or. Worth some brief inline jsdocs?
| } | ||
|
|
||
| this.initStatus = "IN_PROGRESS"; | ||
| let deferredResolve; |
There was a problem hiding this comment.
Why the deferred resolve and saved initPromise property? This is an anti-pattern we've tried to avoid in other parts of CesiumJS codebase as it can lead to unhandled errors.
Can this all be handle within the Promise constructor? Or could the remainder of this function be captured in it's own async function?
| await crypto.subtle.digest("SHA-256", new TextEncoder().encode(input)), | ||
| ); | ||
| const base64 = result.toBase64({ alphabet: "base64url", omitPadding: true }); | ||
| console.log("base64", base64); |
There was a problem hiding this comment.
Please do a pass and cleanup any rogue console.log statements.
| * table for this if you can spare it, as it uses ~150 bytes per actively logging in user, and | ||
| * public abuse could easily kill your server. | ||
| */ | ||
| const MAX_AGE = 60 * 1000; |
There was a problem hiding this comment.
Is max-age specified in the response headers from ion? Should we be using that instead to account for any upstream changes in ion?
| if (!resp.username) { | ||
| return undefined; | ||
| } | ||
| // TODO: remove just testing |
| // However we should probably add the option to update it in place | ||
| return; | ||
| } | ||
| // TODO: this is an async edit of the code. Probably need a way to lock the editor? |
| } | ||
|
|
||
| /* eslint-disable-next-line no-extend-native */ | ||
| Uint8Array.prototype.toBase64 ??= function toBase64(options) { |
There was a problem hiding this comment.
I think you'll need to add the polyfill before toBase64 is called in sha256. Moving it above the exported function should be suficient.

Description
Adds basic Login functionality using ion oauth. This also provides a "User" context for the whole app so other components can depend on the currently logged in user. As a proof of concept there is a new
Insert > Access tokenoption with the editor that will add your account's default access token to the current sandcastle when logged in. This will be replaced with a selection modal for multiple tokens later.This PR replaces the #13079 PR which had a mix of changes that have already been merged.
Currently login is only enabled in local development because we need to set up additional domains and deployments to securely enable in deployed environments.
Issue number and link
Private repo issue
Testing plan
npm run build-sandcastleto build with the new login UInpm startand open local sandcastleTest fetchwill send a request that can be checked in the network tab, this is also temporaryDenyon the oauth screenAuthor checklist
CONTRIBUTORS.mdCHANGES.mdwith a short summary of my changeAI acknowledgment
If yes, I used the following Tools(s) and/or Service(s):
If yes, I used the following Model(s):