diff --git a/src/components/LoginPage.js b/src/components/LoginPage.js
index 6c439a5..1a78944 100644
--- a/src/components/LoginPage.js
+++ b/src/components/LoginPage.js
@@ -78,11 +78,48 @@ const LoginPage = ({ theme }) => {
const login = useLogin();
const notify = useNotify();
const [loading, setLoading] = useState(false);
+ const [supportPassAuth, setSupportPassAuth] = useState(true);
var locale = useLocale();
const setLocale = useSetLocale();
const translate = useTranslate();
const base_url = localStorage.getItem("base_url");
const cfg_base_url = process.env.REACT_APP_SERVER;
+ const [ssoBaseUrl, setSSOBaseUrl] = useState("");
+ const loginToken = /\?loginToken=([a-zA-Z0-9_-]+)/.exec(window.location.href);
+
+ if (loginToken) {
+ const ssoToken = loginToken[1];
+ console.log("SSO token is", ssoToken);
+ // Prevent further requests
+ window.history.replaceState(
+ {},
+ "",
+ window.location.href.replace(loginToken[0], "#").split("#")[0]
+ );
+ const baseUrl = localStorage.getItem("sso_base_url");
+ localStorage.removeItem("sso_base_url");
+ if (baseUrl) {
+ const auth = {
+ base_url: baseUrl,
+ username: null,
+ password: null,
+ loginToken: ssoToken,
+ };
+ console.log("Base URL is:", baseUrl);
+ console.log("SSO Token is:", ssoToken);
+ console.log("Let's try token login...");
+ login(auth).catch(error => {
+ alert(
+ typeof error === "string"
+ ? error
+ : typeof error === "undefined" || !error.message
+ ? "ra.auth.sign_in_error"
+ : error.message
+ );
+ console.error(error);
+ });
+ }
+ }
const renderInput = ({
meta: { touched, error } = {},
@@ -137,6 +174,14 @@ const LoginPage = ({ theme }) => {
});
};
+ const handleSSO = () => {
+ localStorage.setItem("sso_base_url", ssoBaseUrl);
+ const ssoFullUrl = `${ssoBaseUrl}/_matrix/client/r0/login/sso/redirect?redirectUrl=${encodeURIComponent(
+ window.location.href
+ )}`;
+ window.location.href = ssoFullUrl;
+ };
+
const extractHomeServer = username => {
const usernameRegex = /@[a-zA-Z0-9._=\-/]+:([a-zA-Z0-9\-.]+\.[a-zA-Z]+)/;
if (!username) return null;
@@ -188,6 +233,31 @@ const LoginPage = ({ theme }) => {
.catch(_ => {
setServerVersion("");
});
+
+ // Set SSO Url
+ const authMethodUrl = `${formData.base_url}/_matrix/client/r0/login`;
+ let supportPass = false,
+ supportSSO = false;
+ fetchUtils
+ .fetchJson(authMethodUrl, { method: "GET" })
+ .then(({ json }) => {
+ json.flows.forEach(f => {
+ if (f.type === "m.login.password") {
+ supportPass = true;
+ } else if (f.type === "m.login.sso") {
+ supportSSO = true;
+ }
+ });
+ setSupportPassAuth(supportPass);
+ if (supportSSO) {
+ setSSOBaseUrl(formData.base_url);
+ } else {
+ setSSOBaseUrl("");
+ }
+ })
+ .catch(_ => {
+ setSSOBaseUrl("");
+ });
},
[formData.base_url]
);
@@ -200,7 +270,7 @@ const LoginPage = ({ theme }) => {
name="username"
component={renderInput}
label={translate("ra.auth.username")}
- disabled={loading}
+ disabled={loading || !supportPassAuth}
onBlur={handleUsernameChange}
resettable
fullWidth
@@ -212,7 +282,7 @@ const LoginPage = ({ theme }) => {
component={renderInput}
label={translate("ra.auth.password")}
type="password"
- disabled={loading}
+ disabled={loading || !supportPassAuth}
resettable
fullWidth
/>
@@ -273,13 +343,24 @@ const LoginPage = ({ theme }) => {
variant="contained"
type="submit"
color="primary"
- disabled={loading}
+ disabled={loading || !supportPassAuth}
className={classes.button}
fullWidth
>
{loading && }
{translate("ra.auth.sign_in")}
+
diff --git a/src/i18n/de.js b/src/i18n/de.js
index ced6512..9688468 100644
--- a/src/i18n/de.js
+++ b/src/i18n/de.js
@@ -10,6 +10,7 @@ const de = {
username_error: "Bitte vollständigen Nutzernamen angeben: '@user:domain'",
protocol_error: "Die URL muss mit 'http://' oder 'https://' beginnen",
url_error: "Keine gültige Matrix Server URL",
+ sso_sign_in: "Anmeldung mit SSO",
},
users: {
invalid_user_id: "Lokaler Anteil der Matrix Benutzer-ID ohne Homeserver.",
diff --git a/src/i18n/en.js b/src/i18n/en.js
index 44e6ed2..b1e379a 100644
--- a/src/i18n/en.js
+++ b/src/i18n/en.js
@@ -10,6 +10,7 @@ const en = {
username_error: "Please enter fully qualified user ID: '@user:domain'",
protocol_error: "URL has to start with 'http://' or 'https://'",
url_error: "Not a valid Matrix server URL",
+ sso_sign_in: "Sign in with SSO",
},
users: {
invalid_user_id: "Localpart of a Matrix user-id without homeserver.",
diff --git a/src/i18n/zh.js b/src/i18n/zh.js
index 3c36366..7a9b4e7 100644
--- a/src/i18n/zh.js
+++ b/src/i18n/zh.js
@@ -10,10 +10,12 @@ const zh = {
username_error: "请输入完整有效的用户 ID: '@user:domain'",
protocol_error: "URL 需要以'http://'或'https://'作为起始",
url_error: "不是一个有效的 Matrix 服务器地址",
+ sso_sign_in: "使用 SSO 登录",
},
users: {
invalid_user_id:
"必须要是一个有效的 Matrix 用户 ID ,例如 @user_id:homeserver",
+ tabs: { sso: "SSO" },
},
rooms: {
tabs: {
diff --git a/src/synapse/authProvider.js b/src/synapse/authProvider.js
index 470637f..723f155 100644
--- a/src/synapse/authProvider.js
+++ b/src/synapse/authProvider.js
@@ -2,20 +2,31 @@ import { fetchUtils } from "react-admin";
const authProvider = {
// called when the user attempts to log in
- login: ({ base_url, username, password }) => {
+ login: ({ base_url, username, password, loginToken }) => {
// force homeserver for protection in case the form is manipulated
base_url = process.env.REACT_APP_SERVER || base_url;
console.log("login ");
const options = {
method: "POST",
- body: JSON.stringify({
- type: "m.login.password",
- user: username,
- password: password,
- device_id: localStorage.getItem("device_id"),
- initial_device_display_name: "Synapse Admin",
- }),
+ body: JSON.stringify(
+ Object.assign(
+ {
+ device_id: localStorage.getItem("device_id"),
+ initial_device_display_name: "Synapse Admin",
+ },
+ loginToken
+ ? {
+ type: "m.login.token",
+ token: loginToken,
+ }
+ : {
+ type: "m.login.password",
+ user: username,
+ password: password,
+ }
+ )
+ ),
};
// use the base_url from login instead of the well_known entry from the