@authon/react 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ko.md ADDED
@@ -0,0 +1,227 @@
1
+ [English](./README.md) | **한국어**
2
+
3
+ # @authon/react
4
+
5
+ [Authon](https://authon.dev)용 React SDK — Provider, 훅, 사전 빌드된 컴포넌트를 제공합니다.
6
+
7
+ ## 설치
8
+
9
+ ```bash
10
+ npm install @authon/react
11
+ # 또는
12
+ pnpm add @authon/react
13
+ ```
14
+
15
+ `react >= 18.0.0`이 필요합니다.
16
+
17
+ ## 빠른 시작
18
+
19
+ ```tsx
20
+ import {
21
+ AuthonProvider,
22
+ SignedIn,
23
+ SignedOut,
24
+ UserButton,
25
+ useUser,
26
+ useAuthon,
27
+ } from '@authon/react';
28
+
29
+ function App() {
30
+ return (
31
+ <AuthonProvider publishableKey="pk_live_...">
32
+ <Header />
33
+ <Main />
34
+ </AuthonProvider>
35
+ );
36
+ }
37
+
38
+ function Header() {
39
+ return (
40
+ <nav>
41
+ <SignedIn>
42
+ <UserButton />
43
+ </SignedIn>
44
+ <SignedOut>
45
+ <SignInButton />
46
+ </SignedOut>
47
+ </nav>
48
+ );
49
+ }
50
+
51
+ function SignInButton() {
52
+ const { openSignIn } = useAuthon();
53
+ return <button onClick={() => openSignIn()}>Sign In</button>;
54
+ }
55
+
56
+ function Main() {
57
+ const { user, isLoading } = useUser();
58
+ if (isLoading) return <p>Loading...</p>;
59
+ if (!user) return <p>Please sign in.</p>;
60
+ return <h1>Welcome, {user.displayName}</h1>;
61
+ }
62
+ ```
63
+
64
+ ## API 레퍼런스
65
+
66
+ ### `<AuthonProvider>`
67
+
68
+ 앱을 감싸며 인증 컨텍스트를 제공합니다.
69
+
70
+ ```tsx
71
+ <AuthonProvider
72
+ publishableKey="pk_live_..."
73
+ config={{
74
+ apiUrl: 'https://api.authon.dev',
75
+ theme: 'auto',
76
+ locale: 'en',
77
+ appearance: { primaryColorStart: '#7c3aed' },
78
+ }}
79
+ >
80
+ {children}
81
+ </AuthonProvider>
82
+ ```
83
+
84
+ ### 훅
85
+
86
+ #### `useAuthon()`
87
+
88
+ 전체 인증 컨텍스트를 반환합니다.
89
+
90
+ ```ts
91
+ const {
92
+ isSignedIn, // boolean
93
+ isLoading, // boolean
94
+ user, // AuthonUser | null
95
+ signOut, // () => Promise<void>
96
+ openSignIn, // () => Promise<void>
97
+ openSignUp, // () => Promise<void>
98
+ getToken, // () => string | null
99
+ client, // Authon instance
100
+ } = useAuthon();
101
+ ```
102
+
103
+ #### `useUser()`
104
+
105
+ 사용자 데이터 간단 접근용 훅입니다.
106
+
107
+ ```ts
108
+ const { user, isLoading } = useUser();
109
+ ```
110
+
111
+ ### 컴포넌트
112
+
113
+ | 컴포넌트 | Props | 설명 |
114
+ |---------|-------|------|
115
+ | `<SignedIn>` | `children` | 로그인 상태일 때만 자식 컴포넌트를 렌더링합니다 |
116
+ | `<SignedOut>` | `children` | 로그아웃 상태일 때만 자식 컴포넌트를 렌더링합니다 |
117
+ | `<UserButton>` | 없음 | 로그아웃 액션이 포함된 아바타 드롭다운입니다 |
118
+ | `<SignIn>` | `mode?` | 로그인 모달을 열거나 인라인 폼을 렌더링합니다 |
119
+ | `<SignUp>` | `mode?` | 회원가입 모달을 열거나 인라인 폼을 렌더링합니다 |
120
+ | `<Protect>` | `fallback?`, `condition?` | 콘텐츠를 보호하며, 선택적으로 커스텀 조건을 지정할 수 있습니다 |
121
+
122
+ ### `<Protect>` 사용 예시
123
+
124
+ ```tsx
125
+ <Protect
126
+ fallback={<p>You need admin access.</p>}
127
+ condition={(user) => user.publicMetadata?.role === 'admin'}
128
+ >
129
+ <AdminPanel />
130
+ </Protect>
131
+ ```
132
+
133
+ ## 다중 인증 (MFA)
134
+
135
+ `useAuthonMfa` 훅을 사용하여 TOTP 기반 MFA(Google Authenticator, Authy 등)를 관리합니다.
136
+
137
+ ### MFA 설정
138
+
139
+ ```tsx
140
+ import { useAuthonMfa } from '@authon/react';
141
+
142
+ function MfaSetup() {
143
+ const { setupMfa, verifyMfaSetup, isLoading, error } = useAuthonMfa();
144
+ const [qrSvg, setQrSvg] = useState('');
145
+ const [backupCodes, setBackupCodes] = useState<string[]>([]);
146
+ const [code, setCode] = useState('');
147
+
148
+ const handleSetup = async () => {
149
+ const result = await setupMfa();
150
+ if (result) {
151
+ setQrSvg(result.qrCodeSvg);
152
+ setBackupCodes(result.backupCodes);
153
+ }
154
+ };
155
+
156
+ const handleVerify = async () => {
157
+ const success = await verifyMfaSetup(code);
158
+ if (success) alert('MFA enabled!');
159
+ };
160
+
161
+ return (
162
+ <div>
163
+ <button onClick={handleSetup} disabled={isLoading}>Enable MFA</button>
164
+ {qrSvg && (
165
+ <>
166
+ <div dangerouslySetInnerHTML={{ __html: qrSvg }} />
167
+ <p>Scan this QR code with your authenticator app</p>
168
+ <input value={code} onChange={(e) => setCode(e.target.value)} placeholder="6-digit code" />
169
+ <button onClick={handleVerify}>Verify</button>
170
+ </>
171
+ )}
172
+ {error && <p style={{ color: 'red' }}>{error.message}</p>}
173
+ </div>
174
+ );
175
+ }
176
+ ```
177
+
178
+ ### MFA 로그인
179
+
180
+ ```tsx
181
+ import { useAuthon } from '@authon/react';
182
+ import { useAuthonMfa } from '@authon/react';
183
+ import { AuthonMfaRequiredError } from '@authon/js';
184
+
185
+ function SignIn() {
186
+ const { client } = useAuthon();
187
+ const { verifyMfa } = useAuthonMfa();
188
+ const [mfaToken, setMfaToken] = useState('');
189
+
190
+ const handleSignIn = async (email: string, password: string) => {
191
+ try {
192
+ await client!.signInWithEmail(email, password);
193
+ } catch (err) {
194
+ if (err instanceof AuthonMfaRequiredError) {
195
+ setMfaToken(err.mfaToken); // Show MFA input
196
+ }
197
+ }
198
+ };
199
+
200
+ const handleMfaVerify = async (code: string) => {
201
+ await verifyMfa(mfaToken, code);
202
+ };
203
+
204
+ // ...
205
+ }
206
+ ```
207
+
208
+ ### `useAuthonMfa()` 레퍼런스
209
+
210
+ | 프로퍼티 / 메서드 | 타입 | 설명 |
211
+ |-----------------|------|------|
212
+ | `setupMfa()` | `Promise<MfaSetupResponse & { qrCodeSvg: string } \| null>` | MFA 설정을 시작합니다 |
213
+ | `verifyMfaSetup(code)` | `Promise<boolean>` | TOTP 코드를 검증하여 설정을 완료합니다 |
214
+ | `verifyMfa(mfaToken, code)` | `Promise<boolean>` | 로그인 시 TOTP 코드를 검증합니다 |
215
+ | `disableMfa(code)` | `Promise<boolean>` | MFA를 비활성화합니다 |
216
+ | `getMfaStatus()` | `Promise<MfaStatus \| null>` | MFA 상태를 조회합니다 |
217
+ | `regenerateBackupCodes(code)` | `Promise<string[] \| null>` | 백업 코드를 재생성합니다 |
218
+ | `isLoading` | `boolean` | 로딩 상태입니다 |
219
+ | `error` | `Error \| null` | 마지막으로 발생한 오류입니다 |
220
+
221
+ ## 문서
222
+
223
+ [authon.dev/docs](https://authon.dev/docs)
224
+
225
+ ## 라이선스
226
+
227
+ [MIT](../../LICENSE)