mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-06-24 12:20:35 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 93f882e460 | |||
| aaa5f4cb2f |
@@ -0,0 +1,22 @@
|
||||
import type { SVGProps } from "react";
|
||||
|
||||
export function LocalAuthIcon(props: SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M8 7a4 4 0 1 0 8 0a4 4 0 0 0-8 0M6 21v-2a4 4 0 0 1 4-4h5m3.5 3.5L15 22l-1.5-1.5m5.054-2.086a2 2 0 1 1 2.828-2.828a2 2 0 0 1-2.828 2.828M16 19l1 1"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -37,6 +37,13 @@ import { useMutation } from "@tanstack/react-query";
|
||||
import axios from "axios";
|
||||
import { toast } from "sonner";
|
||||
import { useEffect } from "react";
|
||||
import { GoogleIcon } from "../icons/google";
|
||||
import { GithubIcon } from "../icons/github";
|
||||
import { TailscaleIcon } from "../icons/tailscale";
|
||||
import { MicrosoftIcon } from "../icons/microsoft";
|
||||
import { PocketIDIcon } from "../icons/pocket-id";
|
||||
import { LocalAuthIcon } from "../icons/local-auth";
|
||||
import { OAuthIcon } from "../icons/oauth";
|
||||
|
||||
function Avatar({ initial }: { initial: string }) {
|
||||
return (
|
||||
@@ -49,8 +56,18 @@ function Avatar({ initial }: { initial: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
const iconStyles = "size-4";
|
||||
|
||||
const iconMap: Record<string, React.ReactNode> = {
|
||||
google: <GoogleIcon className={iconStyles} />,
|
||||
github: <GithubIcon className={iconStyles} />,
|
||||
tailscale: <TailscaleIcon className={iconStyles} />,
|
||||
microsoft: <MicrosoftIcon className={iconStyles} />,
|
||||
pocketid: <PocketIDIcon className={iconStyles} />,
|
||||
};
|
||||
|
||||
export const QuickActions = () => {
|
||||
const { auth } = useUserContext();
|
||||
const { auth, oauth, tailscale } = useUserContext();
|
||||
const { theme, setTheme } = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const { search } = useLocation();
|
||||
@@ -64,6 +81,41 @@ export const QuickActions = () => {
|
||||
const screenParams = useScreenParams(searchParams);
|
||||
const compiledParams = recompileScreenParams(screenParams);
|
||||
|
||||
const providerDetails = (():
|
||||
| { name: string; icon: React.ReactNode }
|
||||
| undefined => {
|
||||
if (!auth.authenticated) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (auth.providerId === "local" || auth.providerId === "ldap") {
|
||||
return {
|
||||
name: t(
|
||||
auth.providerId === "ldap"
|
||||
? "quickActionsProviderLDAP"
|
||||
: "quickActionsProviderLocal",
|
||||
),
|
||||
icon: <LocalAuthIcon className={iconStyles} />,
|
||||
};
|
||||
}
|
||||
|
||||
if (oauth.active) {
|
||||
return {
|
||||
name: t("quickActionsProviderOAuth", { provider: oauth.displayName }),
|
||||
icon: iconMap[auth.providerId] || <OAuthIcon className={iconStyles} />,
|
||||
};
|
||||
}
|
||||
|
||||
if (auth.providerId === "tailscale") {
|
||||
return {
|
||||
name: `Tailscale (${tailscale.nodeName})`,
|
||||
icon: <TailscaleIcon className={iconStyles} />,
|
||||
};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
})();
|
||||
|
||||
const logoutMutation = useMutation({
|
||||
mutationFn: () => axios.post("/api/user/logout"),
|
||||
mutationKey: ["logout"],
|
||||
@@ -134,11 +186,19 @@ export const QuickActions = () => {
|
||||
<div className="bg-foreground text-background flex size-9 shrink-0 items-center justify-center rounded-full text-sm font-medium">
|
||||
{initial}
|
||||
</div>
|
||||
<div className="flex min-w-0 flex-col">
|
||||
<span className="truncate text-sm font-medium">
|
||||
{auth.name}
|
||||
</span>
|
||||
<span className="text-muted-foreground truncate text-xs font-normal">
|
||||
<div className="flex min-w-0 flex-col gap-1.5">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="truncate text-sm font-medium leading-none">
|
||||
{auth.name}
|
||||
</span>
|
||||
{providerDetails && (
|
||||
<span className="text-muted-foreground inline-flex shrink-0 items-center gap-1 rounded-lg bg-secondary px-2 py-1.25 text-[10px] font-medium leading-none [&_svg]:size-3">
|
||||
{providerDetails.icon}
|
||||
{providerDetails.name}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<span className="text-muted-foreground truncate text-xs leading-none">
|
||||
{auth.email}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -99,5 +99,8 @@
|
||||
"quickActionsThemeDark": "Dark",
|
||||
"quickActionsThemeSystem": "System",
|
||||
"quickActionsLogout": "Logout",
|
||||
"quickActionsTitle": "Quick Actions"
|
||||
"quickActionsTitle": "Quick Actions",
|
||||
"quickActionsProviderLocal": "Local",
|
||||
"quickActionsProviderLDAP": "LDAP",
|
||||
"quickActionsProviderOAuth": "{{provider}} OAuth"
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"syscall"
|
||||
@@ -131,6 +132,10 @@ func (app *BootstrapApp) Setup() error {
|
||||
app.runtime.OAuthProviders = app.config.OAuth.Providers
|
||||
|
||||
for id, provider := range app.runtime.OAuthProviders {
|
||||
if slices.Contains(model.ReservedProviderNames, id) {
|
||||
return fmt.Errorf("provider id %s is reserved and cannot be used", id)
|
||||
}
|
||||
|
||||
providerWhitelist, err := utils.GetStringList(provider.Whitelist, provider.WhitelistFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load oauth whitelist for provider %s: %w", id, err)
|
||||
|
||||
@@ -17,6 +17,8 @@ var OverrideProviders = map[string]string{
|
||||
"github": "GitHub",
|
||||
}
|
||||
|
||||
var ReservedProviderNames = []string{"local", "ldap", "tailscale"}
|
||||
|
||||
const SessionCookieName = "tinyauth-session"
|
||||
const CSRFCookieName = "tinyauth-csrf"
|
||||
const RedirectCookieName = "tinyauth-redirect"
|
||||
|
||||
Reference in New Issue
Block a user