mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2024-12-24 20:14:53 +01:00
Generate the OIDC redirect URI from the URLRouter
This also saves the redirectUri during the flow
This commit is contained in:
parent
dac68f362a
commit
d723561d66
@ -49,10 +49,11 @@ export class CompleteOIDCLoginViewModel extends ViewModel {
|
|||||||
}
|
}
|
||||||
const code = this._code;
|
const code = this._code;
|
||||||
// TODO: cleanup settings storage
|
// TODO: cleanup settings storage
|
||||||
const [startedAt, nonce, codeVerifier, homeserver, issuer] = await Promise.all([
|
const [startedAt, nonce, codeVerifier, redirectUri, homeserver, issuer] = await Promise.all([
|
||||||
this.platform.settingsStorage.getInt(`oidc_${this._state}_started_at`),
|
this.platform.settingsStorage.getInt(`oidc_${this._state}_started_at`),
|
||||||
this.platform.settingsStorage.getString(`oidc_${this._state}_nonce`),
|
this.platform.settingsStorage.getString(`oidc_${this._state}_nonce`),
|
||||||
this.platform.settingsStorage.getString(`oidc_${this._state}_code_verifier`),
|
this.platform.settingsStorage.getString(`oidc_${this._state}_code_verifier`),
|
||||||
|
this.platform.settingsStorage.getString(`oidc_${this._state}_redirect_uri`),
|
||||||
this.platform.settingsStorage.getString(`oidc_${this._state}_homeserver`),
|
this.platform.settingsStorage.getString(`oidc_${this._state}_homeserver`),
|
||||||
this.platform.settingsStorage.getString(`oidc_${this._state}_issuer`),
|
this.platform.settingsStorage.getString(`oidc_${this._state}_issuer`),
|
||||||
]);
|
]);
|
||||||
@ -63,7 +64,7 @@ export class CompleteOIDCLoginViewModel extends ViewModel {
|
|||||||
request: this._request,
|
request: this._request,
|
||||||
encoding: this._encoding,
|
encoding: this._encoding,
|
||||||
});
|
});
|
||||||
const method = new OIDCLoginMethod({oidcApi, nonce, codeVerifier, code, homeserver, startedAt});
|
const method = new OIDCLoginMethod({oidcApi, nonce, codeVerifier, code, homeserver, startedAt, redirectUri});
|
||||||
const status = await this._attemptLogin(method);
|
const status = await this._attemptLogin(method);
|
||||||
let error = "";
|
let error = "";
|
||||||
switch (status) {
|
switch (status) {
|
||||||
|
@ -44,11 +44,15 @@ export class StartOIDCLoginViewModel extends ViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async startOIDCLogin() {
|
async startOIDCLogin() {
|
||||||
const p = this._api.generateParams("openid");
|
const p = this._api.generateParams({
|
||||||
|
scope: "openid",
|
||||||
|
redirectUri: this.urlCreator.createOIDCRedirectURL(),
|
||||||
|
});
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.platform.settingsStorage.setInt(`oidc_${p.state}_started_at`, Date.now()),
|
this.platform.settingsStorage.setInt(`oidc_${p.state}_started_at`, Date.now()),
|
||||||
this.platform.settingsStorage.setString(`oidc_${p.state}_nonce`, p.nonce),
|
this.platform.settingsStorage.setString(`oidc_${p.state}_nonce`, p.nonce),
|
||||||
this.platform.settingsStorage.setString(`oidc_${p.state}_code_verifier`, p.codeVerifier),
|
this.platform.settingsStorage.setString(`oidc_${p.state}_code_verifier`, p.codeVerifier),
|
||||||
|
this.platform.settingsStorage.setString(`oidc_${p.state}_redirect_uri`, p.redirectUri),
|
||||||
this.platform.settingsStorage.setString(`oidc_${p.state}_homeserver`, this._homeserver),
|
this.platform.settingsStorage.setString(`oidc_${p.state}_homeserver`, this._homeserver),
|
||||||
this.platform.settingsStorage.setString(`oidc_${p.state}_issuer`, this._issuer),
|
this.platform.settingsStorage.setString(`oidc_${p.state}_issuer`, this._issuer),
|
||||||
]);
|
]);
|
||||||
|
@ -125,6 +125,10 @@ export class URLRouter {
|
|||||||
return window.location.origin;
|
return window.location.origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createOIDCRedirectURL() {
|
||||||
|
return window.location.origin;
|
||||||
|
}
|
||||||
|
|
||||||
normalizeUrl() {
|
normalizeUrl() {
|
||||||
// Remove any queryParameters from the URL
|
// Remove any queryParameters from the URL
|
||||||
// Gets rid of the loginToken after SSO
|
// Gets rid of the loginToken after SSO
|
||||||
|
@ -23,6 +23,7 @@ export class OIDCLoginMethod implements ILoginMethod {
|
|||||||
private readonly _code: string;
|
private readonly _code: string;
|
||||||
private readonly _codeVerifier: string;
|
private readonly _codeVerifier: string;
|
||||||
private readonly _nonce: string;
|
private readonly _nonce: string;
|
||||||
|
private readonly _redirectUri: string;
|
||||||
private readonly _oidcApi: OidcApi;
|
private readonly _oidcApi: OidcApi;
|
||||||
public readonly homeserver: string;
|
public readonly homeserver: string;
|
||||||
|
|
||||||
@ -31,18 +32,21 @@ export class OIDCLoginMethod implements ILoginMethod {
|
|||||||
codeVerifier,
|
codeVerifier,
|
||||||
code,
|
code,
|
||||||
homeserver,
|
homeserver,
|
||||||
|
redirectUri,
|
||||||
oidcApi,
|
oidcApi,
|
||||||
}: {
|
}: {
|
||||||
nonce: string,
|
nonce: string,
|
||||||
code: string,
|
code: string,
|
||||||
codeVerifier: string,
|
codeVerifier: string,
|
||||||
homeserver: string,
|
homeserver: string,
|
||||||
|
redirectUri: string,
|
||||||
oidcApi: OidcApi,
|
oidcApi: OidcApi,
|
||||||
}) {
|
}) {
|
||||||
this._oidcApi = oidcApi;
|
this._oidcApi = oidcApi;
|
||||||
this._code = code;
|
this._code = code;
|
||||||
this._codeVerifier = codeVerifier;
|
this._codeVerifier = codeVerifier;
|
||||||
this._nonce = nonce;
|
this._nonce = nonce;
|
||||||
|
this._redirectUri = redirectUri;
|
||||||
this.homeserver = homeserver;
|
this.homeserver = homeserver;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,6 +54,7 @@ export class OIDCLoginMethod implements ILoginMethod {
|
|||||||
const { access_token, refresh_token, expires_in } = await this._oidcApi.completeAuthorizationCodeGrant({
|
const { access_token, refresh_token, expires_in } = await this._oidcApi.completeAuthorizationCodeGrant({
|
||||||
code: this._code,
|
code: this._code,
|
||||||
codeVerifier: this._codeVerifier,
|
codeVerifier: this._codeVerifier,
|
||||||
|
redirectUri: this._redirectUri,
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: validate the id_token and the nonce claim
|
// TODO: validate the id_token and the nonce claim
|
||||||
|
@ -39,6 +39,7 @@ const isValidBearerToken = (t: any): t is BearerToken =>
|
|||||||
type AuthorizationParams = {
|
type AuthorizationParams = {
|
||||||
state: string,
|
state: string,
|
||||||
scope: string,
|
scope: string,
|
||||||
|
redirectUri: string,
|
||||||
nonce?: string,
|
nonce?: string,
|
||||||
codeVerifier?: string,
|
codeVerifier?: string,
|
||||||
};
|
};
|
||||||
@ -118,6 +119,7 @@ export class OidcApi {
|
|||||||
|
|
||||||
async authorizationEndpoint({
|
async authorizationEndpoint({
|
||||||
state,
|
state,
|
||||||
|
redirectUri,
|
||||||
scope,
|
scope,
|
||||||
nonce,
|
nonce,
|
||||||
codeVerifier,
|
codeVerifier,
|
||||||
@ -126,7 +128,7 @@ export class OidcApi {
|
|||||||
const url = new URL(metadata["authorization_endpoint"]);
|
const url = new URL(metadata["authorization_endpoint"]);
|
||||||
url.searchParams.append("response_mode", "fragment");
|
url.searchParams.append("response_mode", "fragment");
|
||||||
url.searchParams.append("response_type", "code");
|
url.searchParams.append("response_type", "code");
|
||||||
url.searchParams.append("redirect_uri", this.redirectUri);
|
url.searchParams.append("redirect_uri", redirectUri);
|
||||||
url.searchParams.append("client_id", this._clientId);
|
url.searchParams.append("client_id", this._clientId);
|
||||||
url.searchParams.append("state", state);
|
url.searchParams.append("state", state);
|
||||||
url.searchParams.append("scope", scope);
|
url.searchParams.append("scope", scope);
|
||||||
@ -147,9 +149,10 @@ export class OidcApi {
|
|||||||
return metadata["token_endpoint"];
|
return metadata["token_endpoint"];
|
||||||
}
|
}
|
||||||
|
|
||||||
generateParams(scope: string): AuthorizationParams {
|
generateParams({ scope, redirectUri }: { scope: string, redirectUri: string }): AuthorizationParams {
|
||||||
return {
|
return {
|
||||||
scope,
|
scope,
|
||||||
|
redirectUri,
|
||||||
state: randomString(8),
|
state: randomString(8),
|
||||||
nonce: randomString(8),
|
nonce: randomString(8),
|
||||||
codeVerifier: randomString(32),
|
codeVerifier: randomString(32),
|
||||||
@ -159,12 +162,13 @@ export class OidcApi {
|
|||||||
async completeAuthorizationCodeGrant({
|
async completeAuthorizationCodeGrant({
|
||||||
codeVerifier,
|
codeVerifier,
|
||||||
code,
|
code,
|
||||||
}: { codeVerifier: string, code: string }): Promise<BearerToken> {
|
redirectUri,
|
||||||
|
}: { codeVerifier: string, code: string, redirectUri: string }): Promise<BearerToken> {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.append("grant_type", "authorization_code");
|
params.append("grant_type", "authorization_code");
|
||||||
params.append("client_id", this._clientId);
|
params.append("client_id", this._clientId);
|
||||||
params.append("code_verifier", codeVerifier);
|
params.append("code_verifier", codeVerifier);
|
||||||
params.append("redirect_uri", this.redirectUri);
|
params.append("redirect_uri", redirectUri);
|
||||||
params.append("code", code);
|
params.append("code", code);
|
||||||
const body = params.toString();
|
const body = params.toString();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user