@suphark/auth-ui
v0.2.1
Published
Prebuilt React components for apps on Pi Auth — SignedIn/SignedOut/Protect, SignInButton/SignOutButton, UserButton (Clerk-style) built on @suphark/ui and @suphark/auth-client
Maintainers
Readme
@suphark/auth-ui
Prebuilt UI สำหรับแอปที่ต่อ Pi Auth — ใช้คู่กับ @suphark/auth-client (session/token) และ @suphark/ui (design system)
เทียบเท่า <UserButton/>, <SignedIn/>, <Protect/> ของ Clerk แต่หน้า "จัดการบัญชี" เป็น hosted page ที่ Pi Auth (/account) ไม่ต้องสร้างใหม่ทุกแอป
ติดตั้ง
pnpm add @suphark/auth-ui @suphark/auth-client @suphark/ui lucide-reactแพ็กเกจส่ง source (TSX) เหมือน @suphark/ui — ตั้ง transpilePackages ใน next.config.ts:
const nextConfig = { transpilePackages: ["@suphark/ui", "@suphark/auth-ui"] };ตั้งค่า (root layout)
import { PiAuthProvider } from "@suphark/auth-client/react";
import { PiAuthUiProvider } from "@suphark/auth-ui";
import { piAuth } from "@/lib/pi-auth";
export default async function RootLayout({ children }) {
const user = await piAuth.getUser();
return (
<PiAuthProvider user={user}>
<PiAuthUiProvider issuer={process.env.NEXT_PUBLIC_PI_AUTH_ISSUER!} appName="DueBell">
{children}
</PiAuthUiProvider>
</PiAuthProvider>
);
}| prop | ค่าเริ่มต้น | ความหมาย |
| --- | --- | --- |
| issuer | — | URL ของ Pi Auth เช่น https://auth.suphark.com (ไม่มี /api/auth) ใช้สร้างลิงก์ไปหน้า hosted |
| basePath | /auth | path ที่ mount handlers ของ SDK ในแอป (/auth/login, /auth/logout) |
| appName | — | ชื่อแอป (ใช้ในข้อความ) |
| labels | ไทย | override ข้อความ — ใช้ DEFAULT_LABELS_EN สำหรับอังกฤษ |
Components
import { SignedIn, SignedOut, Protect, SignInButton, SignOutButton, UserButton, OrganizationSwitcher } from "@suphark/auth-ui";
<SignedOut><SignInButton /></SignedOut>
<SignedIn><UserButton /></SignedIn>
<Protect permission="invoice:approve" fallback={<p>ไม่มีสิทธิ์</p>}>
<ApproveButton />
</Protect>
<Protect permission={["a", "b"]} any>…</Protect><UserButton>
ปุ่ม avatar + เมนู (สร้างจาก UserMenu ของ @suphark/ui/next) — รายการ:
- จัดการบัญชี →
{issuer}/account?return_to=<หน้าปัจจุบัน> - ความปลอดภัย →
{issuer}/account/security?return_to=… - องค์กรของฉัน →
{issuer}/console(ปิดด้วยshowOrganization={false}) children— รายการเพิ่มของแอป (เช่น<ThemeMenuItems/>จาก@suphark/ui)- ออกจากระบบ (local: ออกเฉพาะแอปนี้) / ออกจากทุกแอป (
showSignOutEverywhere)
props: variant="header" | "sidebar", mode="redirect" | "modal", afterSignOutUrl, className
mode="modal": จัดการบัญชี/ความปลอดภัยเปิดใน dialog (iframe ของ /account?embed=1) ไม่ต้องออกจากแอป — ต้องเป็นแอป same-site กับ Pi Auth (subdomain เดียวกัน) และ origin ของแอปอยู่ใน PI_AUTH_EMBED_ORIGINS ของ Pi Auth; ใช้ <AccountDialog open onOpenChange path="/account/security" /> เองก็ได้
หน้า /account ของ Pi Auth จะแสดงปุ่ม "กลับไป {ชื่อแอป}" เมื่อ return_to มี origin ตรงกับ redirect URI ที่ลงทะเบียนไว้ของแอป
<OrganizationSwitcher>
เมนูสลับองค์กร (ต้องขอ scope tenant และ @suphark/auth-client >= 0.1.6 เพื่อให้ user.tenants มีค่า)
- แสดงองค์กรที่ active + รายชื่อองค์กรทั้งหมดที่เป็นสมาชิก; เลือกแล้วไป
/auth/login?tenant=<slug>&next=<หน้าปัจจุบัน>(สลับผ่าน OIDC ไม่ต้องล็อกอินใหม่) - จัดการองค์กร →
{issuer}/console(ปิดด้วยshowManageOrganization={false}) - props:
variant="header" | "sidebar",afterSelectOrganizationUrl(path ในแอป),className,children(รายการเพิ่ม)
<SignInButton> / <SignOutButton>
ห่อ Button ของ @suphark/ui รับ props ของ Button ทั้งหมด
SignInButton next="/dashboard" tenant="acme"—nextค่าเริ่มต้น = หน้าปัจจุบันSignOutButton scope="local" | "all" next="/"— ไม่ระบุscope= ตามlogoutScopeของ SDK
helpers
hostedUrl(issuer, path, returnTo), loginUrl(basePath, next, tenant), logoutUrl(basePath, scope, next), safeNext(value) — ใช้เมื่อประกอบเมนูเอง
ข้อกำหนด
- React 19, Next.js 15+ (client components — ทุกไฟล์มี
"use client") @suphark/auth-client>= 0.1.6,@suphark/ui>= 0.3.1- ต้องมี
<PiAuthProvider user>ของ SDK อยู่นอก<PiAuthUiProvider>
License
MIT
