Skip to content

Commit a57c430

Browse files
Implementation of MSC3824 to add action= param on SSO login (#2398)
Co-authored-by: Šimon Brandner <simon.bra.ag@gmail.com>
1 parent 583e480 commit a57c430

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

spec/unit/login.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { SSOAction } from '../../src/@types/auth';
12
import { TestClient } from '../TestClient';
23

34
describe('Login request', function() {
@@ -22,3 +23,37 @@ describe('Login request', function() {
2223
expect(client.client.getUserId()).toBe(response.user_id);
2324
});
2425
});
26+
27+
describe('SSO login URL', function() {
28+
let client: TestClient;
29+
30+
beforeEach(function() {
31+
client = new TestClient();
32+
});
33+
34+
afterEach(function() {
35+
client.stop();
36+
});
37+
38+
describe('SSOAction', function() {
39+
const redirectUri = "https://test.com/foo";
40+
41+
it('No action', function() {
42+
const urlString = client.client.getSsoLoginUrl(redirectUri, undefined, undefined, undefined);
43+
const url = new URL(urlString);
44+
expect(url.searchParams.has('org.matrix.msc3824.action')).toBe(false);
45+
});
46+
47+
it('register', function() {
48+
const urlString = client.client.getSsoLoginUrl(redirectUri, undefined, undefined, SSOAction.REGISTER);
49+
const url = new URL(urlString);
50+
expect(url.searchParams.get('org.matrix.msc3824.action')).toEqual('register');
51+
});
52+
53+
it('login', function() {
54+
const urlString = client.client.getSsoLoginUrl(redirectUri, undefined, undefined, SSOAction.LOGIN);
55+
const url = new URL(urlString);
56+
expect(url.searchParams.get('org.matrix.msc3824.action')).toEqual('login');
57+
});
58+
});
59+
});

src/@types/auth.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,11 @@ export interface ILoginParams {
8282
initial_device_display_name?: string;
8383
}
8484
/* eslint-enable camelcase */
85+
86+
export enum SSOAction {
87+
/** The user intends to login to an existing account */
88+
LOGIN = "login",
89+
90+
/** The user intends to register for a new account */
91+
REGISTER = "register",
92+
}

src/client.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,14 @@ import { IPusher, IPusherRequest, IPushRules, PushRuleAction, PushRuleKind, Rule
188188
import { IThreepid } from "./@types/threepids";
189189
import { CryptoStore } from "./crypto/store/base";
190190
import { MediaHandler } from "./webrtc/mediaHandler";
191-
import { ILoginFlowsResponse, IRefreshTokenResponse } from "./@types/auth";
191+
import { ILoginFlowsResponse, IRefreshTokenResponse, SSOAction } from "./@types/auth";
192192
import { TypedEventEmitter } from "./models/typed-event-emitter";
193193
import { ReceiptType } from "./@types/read_receipts";
194194
import { MSC3575SlidingSyncRequest, MSC3575SlidingSyncResponse, SlidingSync } from "./sliding-sync";
195195
import { SlidingSyncSdk } from "./sliding-sync-sdk";
196196
import { Thread, THREAD_RELATION_TYPE } from "./models/thread";
197197
import { MBeaconInfoEventContent, M_BEACON_INFO } from "./@types/beacon";
198+
import { UnstableValue } from "./NamespacedValue";
198199
import { ToDeviceMessageQueue } from "./ToDeviceMessageQueue";
199200
import { ToDeviceBatch } from "./models/ToDeviceMessage";
200201
import { IgnoredInvites } from "./models/invites-ignorer";
@@ -881,6 +882,8 @@ export type ClientEventHandlerMap = {
881882
& HttpApiEventHandlerMap
882883
& BeaconEventHandlerMap;
883884

885+
const SSO_ACTION_PARAM = new UnstableValue("action", "org.matrix.msc3824.action");
886+
884887
/**
885888
* Represents a Matrix Client. Only directly construct this if you want to use
886889
* custom modules. Normally, {@link createClient} should be used
@@ -7156,15 +7159,26 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
71567159
* @param {string} loginType The type of SSO login we are doing (sso or cas).
71577160
* Defaults to 'sso'.
71587161
* @param {string} idpId The ID of the Identity Provider being targeted, optional.
7162+
* @param {SSOAction} action the SSO flow to indicate to the IdP, optional.
71597163
* @return {string} The HS URL to hit to begin the SSO login process.
71607164
*/
7161-
public getSsoLoginUrl(redirectUrl: string, loginType = "sso", idpId?: string): string {
7165+
public getSsoLoginUrl(
7166+
redirectUrl: string,
7167+
loginType = "sso",
7168+
idpId?: string,
7169+
action?: SSOAction,
7170+
): string {
71627171
let url = "/login/" + loginType + "/redirect";
71637172
if (idpId) {
71647173
url += "/" + idpId;
71657174
}
71667175

7167-
return this.http.getUrl(url, { redirectUrl }, PREFIX_R0);
7176+
const params = {
7177+
redirectUrl,
7178+
[SSO_ACTION_PARAM.unstable!]: action,
7179+
};
7180+
7181+
return this.http.getUrl(url, params, PREFIX_R0);
71687182
}
71697183

71707184
/**

0 commit comments

Comments
 (0)