mirror of
https://github.com/aykhans/slash-e.git
synced 2025-04-20 22:07:15 +00:00
chore: tweak sso docs
This commit is contained in:
parent
f057cd0078
commit
972b3a3106
@ -15,3 +15,23 @@ As an Admin user, you can create a new SSO provider in Setting > Workspace setti
|
|||||||
For example, to integrate with GitHub, you might need to fill in the following fields:
|
For example, to integrate with GitHub, you might need to fill in the following fields:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
### Identity provider information
|
||||||
|
|
||||||
|
The information is the base concept of OAuth 2.0 and comes from your provider.
|
||||||
|
|
||||||
|
- **Client ID** is a public identifier of the custom provider;
|
||||||
|
- **Client Secret** is the OAuth2 client secret from identity provider;
|
||||||
|
- **Authorization endpoint** is the custom provider's OAuth2 login page address;
|
||||||
|
- **Token endpoint** is the API address for obtaining access token;
|
||||||
|
- **User endpoint** URL is the API address for obtaining user information by access token;
|
||||||
|
- **Scopes** is the scope parameter carried when accessing the OAuth2 URL, which is filled in according to the custom provider;
|
||||||
|
|
||||||
|
### User information mapping
|
||||||
|
|
||||||
|
For different providers, the structures returned by their user information API are usually not the same. In order to know how to map the user information from an provider into user fields, you need to fill the user information mapping form.
|
||||||
|
|
||||||
|
Slash will use the mapping to import the user profile fields when creating new accounts. The most important user field mapping is the identifier which is used to identify the Slash account associated with the OAuth 2.0 login.
|
||||||
|
|
||||||
|
- **Identifier** is the field name of primary email in 3rd-party user info;
|
||||||
|
- **Display name** is the field name of display name in 3rd-party user info (optional);
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
},
|
},
|
||||||
"filter": {
|
"filter": {
|
||||||
"all": "All",
|
"all": "All",
|
||||||
"mine": "Mine",
|
"personal": "Personal",
|
||||||
"compact-mode": "Compact mode",
|
"compact-mode": "Compact mode",
|
||||||
"order-by": "Order by",
|
"order-by": "Order by",
|
||||||
"direction": "Direction"
|
"direction": "Direction"
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
},
|
},
|
||||||
"filter": {
|
"filter": {
|
||||||
"all": "所有",
|
"all": "所有",
|
||||||
"mine": "我的",
|
"personal": "我的",
|
||||||
"compact-mode": "紧凑模式",
|
"compact-mode": "紧凑模式",
|
||||||
"order-by": "排序方式",
|
"order-by": "排序方式",
|
||||||
"direction": "方向"
|
"direction": "方向"
|
||||||
|
@ -152,6 +152,7 @@ const CreateIdentityProviderDrawer: React.FC<Props> = (props: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Divider className="!mb-3" />
|
<Divider className="!mb-3" />
|
||||||
|
<p className="font-medium mb-2">Identity provider information</p>
|
||||||
{isCreating && (
|
{isCreating && (
|
||||||
<p className="shadow-sm rounded-md py-1 px-2 bg-zinc-100 dark:bg-zinc-900 text-sm w-full mb-2 break-all">
|
<p className="shadow-sm rounded-md py-1 px-2 bg-zinc-100 dark:bg-zinc-900 text-sm w-full mb-2 break-all">
|
||||||
<span className="opacity-60">Redirect URL</span>
|
<span className="opacity-60">Redirect URL</span>
|
||||||
@ -244,6 +245,7 @@ const CreateIdentityProviderDrawer: React.FC<Props> = (props: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Divider className="!mb-3" />
|
<Divider className="!mb-3" />
|
||||||
|
<p className="font-medium mb-2">Field mapping</p>
|
||||||
<div className="w-full flex flex-col justify-start items-start mb-3">
|
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||||
<span className="mb-2">
|
<span className="mb-2">
|
||||||
Identifier <span className="text-red-600">*</span>
|
Identifier <span className="text-red-600">*</span>
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { Avatar } from "@mui/joy";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Link, useLocation } from "react-router-dom";
|
import { Link, useLocation } from "react-router-dom";
|
||||||
@ -38,7 +37,8 @@ const Header: React.FC = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
{[PlanType.PRO, PlanType.ENTERPRISE].includes(profile.plan) && (
|
{[PlanType.PRO, PlanType.ENTERPRISE].includes(profile.plan) && (
|
||||||
<span className="ml-1 text-xs px-1.5 leading-5 border rounded-full bg-blue-600 border-blue-700 text-white shadow dark:opacity-70">
|
<span className="ml-1 text-xs px-1.5 leading-5 border rounded-full bg-blue-600 border-blue-700 text-white shadow dark:opacity-70">
|
||||||
{profile.plan}
|
{/* PRO or ENT */}
|
||||||
|
{profile.plan.substring(0, 3)}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{shouldShowRouterSwitch && (
|
{shouldShowRouterSwitch && (
|
||||||
@ -74,13 +74,12 @@ const Header: React.FC = () => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="relative flex-shrink-0">
|
<div className="relative shrink-0">
|
||||||
<Dropdown
|
<Dropdown
|
||||||
trigger={
|
trigger={
|
||||||
<button className="flex flex-row justify-end items-center cursor-pointer">
|
<button className="flex flex-row justify-end items-center cursor-pointer">
|
||||||
<Avatar size="sm" variant="plain" />
|
<span className="dark:text-gray-400 max-w-20 truncate">{currentUser.nickname}</span>
|
||||||
<span className="dark:text-gray-400">{currentUser.nickname}</span>
|
<Icon.ChevronDown className="ml-1 w-5 h-auto text-gray-600 dark:text-gray-400" />
|
||||||
<Icon.ChevronDown className="ml-2 w-5 h-auto text-gray-600 dark:text-gray-400" />
|
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
actionsClassName="!w-32"
|
actionsClassName="!w-32"
|
||||||
|
@ -35,7 +35,7 @@ const ShortcutsNavigator = () => {
|
|||||||
onClick={() => viewStore.setFilter({ tab: "tab:mine" })}
|
onClick={() => viewStore.setFilter({ tab: "tab:mine" })}
|
||||||
>
|
>
|
||||||
<Icon.User className="w-4 h-auto mr-1" />
|
<Icon.User className="w-4 h-auto mr-1" />
|
||||||
<span className="font-normal">{t("filter.mine")}</span>
|
<span className="font-normal">{t("filter.personal")}</span>
|
||||||
</button>
|
</button>
|
||||||
{Array.from(sortedTagMap.keys()).map((tag) => (
|
{Array.from(sortedTagMap.keys()).map((tag) => (
|
||||||
<button
|
<button
|
||||||
|
@ -54,9 +54,17 @@ const SSOSection = () => {
|
|||||||
<>
|
<>
|
||||||
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
||||||
<div className="w-full flex flex-row justify-between items-center gap-1">
|
<div className="w-full flex flex-row justify-between items-center gap-1">
|
||||||
<div className="flex flex-row items-center gap-1">
|
<div className="flex flex-row justify-start items-center">
|
||||||
<span className="font-medium dark:text-gray-400">SSO</span>
|
<span className="font-medium dark:text-gray-400">SSO</span>
|
||||||
<FeatureBadge className="w-5 h-auto ml-1 text-blue-600" feature={FeatureType.SSO} />
|
<FeatureBadge className="w-5 h-auto ml-1 text-blue-600" feature={FeatureType.SSO} />
|
||||||
|
<a
|
||||||
|
className="text-blue-600 text-sm hover:underline flex flex-row justify-center items-center ml-2"
|
||||||
|
href="https://github.com/yourselfhosted/slash/blob/main/docs/getting-started/sso.md"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<span>Learn more</span>
|
||||||
|
<Icon.ExternalLink className="ml-1 w-4 h-auto inline" />
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
@ -27,7 +27,7 @@ const SubscriptionSetting: React.FC = () => {
|
|||||||
licenseKey,
|
licenseKey,
|
||||||
});
|
});
|
||||||
if (subscription) {
|
if (subscription) {
|
||||||
toast.success(`Welcome to Slash-${stringifyPlanType(subscription.plan)}🎉`);
|
toast.success(`Welcome to Slash ${stringifyPlanType(subscription.plan)}🎉`);
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
toast.error(error.details);
|
toast.error(error.details);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user