OIDC: Log in (#11199)

* add delegatedauthentication to validated server config

* dynamic client registration functions

* test OP registration functions

* add stubbed nativeOidc flow setup in Login

* cover more error cases in Login

* tidy

* test dynamic client registration in Login

* comment oidc_static_clients

* register oidc inside Login.getFlows

* strict fixes

* remove unused code

* and imports

* comments

* comments 2

* util functions to get static client id

* check static client ids in login flow

* remove dead code

* OidcRegistrationClientMetadata type

* navigate to oidc authorize url

* exchange code for token

* navigate to oidc authorize url

* navigate to oidc authorize url

* test

* adjust for js-sdk code

* login with oidc native flow: messy version

* tidy

* update test for response_mode query

* tidy up some TODOs

* use new types

* add identityServerUrl to stored params

* unit test completeOidcLogin

* test tokenlogin

* strict

* whitespace

* tidy

* unit test oidc login flow in MatrixChat

* strict

* tidy

* extract success/failure handlers from token login function

* typo

* use for no homeserver error dialog too

* reuse post-token login functions, test

* shuffle testing utils around

* shuffle testing utils around

* i18n

* tidy

* Update src/Lifecycle.ts

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* tidy

* comment

* update tests for id token validation

* move try again responsibility

* prettier

* use more future proof config for static clients

* test util for oidcclientconfigs

* rename type and lint

* correct oidc test util

* store issuer and clientId pre auth navigation

* adjust for js-sdk changes

* update for js-sdk userstate, tidy

* update MatrixChat tests

* update tests

---------

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
This commit is contained in:
Kerry 2023-07-11 16:09:18 +12:00 committed by GitHub
parent 186497a67d
commit 7b3d0ad209
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 490 additions and 67 deletions

View file

@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { completeAuthorizationCodeGrant } from "matrix-js-sdk/src/oidc/authorize";
import { QueryDict } from "matrix-js-sdk/src/utils";
import { OidcClientConfig } from "matrix-js-sdk/src/autodiscovery";
import { generateOidcAuthorizationUrl } from "matrix-js-sdk/src/oidc/authorize";
import { randomString } from "matrix-js-sdk/src/randomstring";
@ -49,3 +51,45 @@ export const startOidcLogin = async (
window.location.href = authorizationUrl;
};
/**
* Gets `code` and `state` query params
*
* @param queryParams
* @returns code and state
* @throws when code and state are not valid strings
*/
const getCodeAndStateFromQueryParams = (queryParams: QueryDict): { code: string; state: string } => {
const code = queryParams["code"];
const state = queryParams["state"];
if (!code || typeof code !== "string" || !state || typeof state !== "string") {
throw new Error("Invalid query parameters for OIDC native login. `code` and `state` are required.");
}
return { code, state };
};
/**
* Attempt to complete authorization code flow to get an access token
* @param queryParams the query-parameters extracted from the real query-string of the starting URI.
* @returns Promise that resolves with accessToken, identityServerUrl, and homeserverUrl when login was successful
* @throws When we failed to get a valid access token
*/
export const completeOidcLogin = async (
queryParams: QueryDict,
): Promise<{
homeserverUrl: string;
identityServerUrl?: string;
accessToken: string;
}> => {
const { code, state } = getCodeAndStateFromQueryParams(queryParams);
const { homeserverUrl, tokenResponse, identityServerUrl } = await completeAuthorizationCodeGrant(code, state);
// @TODO(kerrya) do something with the refresh token https://github.com/vector-im/element-web/issues/25444
return {
homeserverUrl: homeserverUrl,
identityServerUrl: identityServerUrl,
accessToken: tokenResponse.access_token,
};
};