@authon/js 0.2.1 → 0.3.1

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,99 @@
1
+ [English](./README.md) | **한국어**
2
+
3
+ # @authon/js
4
+
5
+ > 브라우저 인증 SDK -- 셀프 호스팅 Clerk 대안, Auth0 대안, 오픈소스 인증
6
+
7
+ ## 설치
8
+
9
+ ```bash
10
+ npm install @authon/js
11
+ ```
12
+
13
+ ## 빠른 시작
14
+
15
+ ```html
16
+ <!DOCTYPE html>
17
+ <html>
18
+ <head><title>My App</title></head>
19
+ <body>
20
+ <button id="sign-in-btn">로그인</button>
21
+ <div id="user-info"></div>
22
+
23
+ <script type="module">
24
+ import { Authon } from '@authon/js';
25
+
26
+ const authon = new Authon('pk_live_YOUR_PUBLISHABLE_KEY', {
27
+ apiUrl: 'https://your-authon-server.com',
28
+ });
29
+
30
+ document.getElementById('sign-in-btn').addEventListener('click', () => {
31
+ authon.openSignIn();
32
+ });
33
+
34
+ authon.on('signedIn', (user) => {
35
+ document.getElementById('user-info').textContent = `안녕하세요, ${user.email}`;
36
+ });
37
+ </script>
38
+ </body>
39
+ </html>
40
+ ```
41
+
42
+ ## 주요 작업
43
+
44
+ ### Google OAuth 로그인 추가
45
+
46
+ ```ts
47
+ await authon.signInWithOAuth('google');
48
+ // 지원 프로바이더: google, apple, github, discord, facebook,
49
+ // microsoft, kakao, naver, line, x
50
+ ```
51
+
52
+ ### 이메일/비밀번호 인증
53
+
54
+ ```ts
55
+ const user = await authon.signUpWithEmail('user@example.com', 'MyP@ssw0rd', { displayName: 'Alice' });
56
+ const user = await authon.signInWithEmail('user@example.com', 'MyP@ssw0rd');
57
+ ```
58
+
59
+ ### 현재 사용자 가져오기
60
+
61
+ ```ts
62
+ const user = authon.getUser();
63
+ const token = authon.getToken();
64
+ ```
65
+
66
+ ### 로그인 모달 열기
67
+
68
+ ```ts
69
+ await authon.openSignIn();
70
+ await authon.openSignUp();
71
+ ```
72
+
73
+ ### 로그아웃
74
+
75
+ ```ts
76
+ await authon.signOut();
77
+ ```
78
+
79
+ ## 환경 변수
80
+
81
+ | 변수 | 필수 | 설명 |
82
+ |------|------|------|
83
+ | `AUTHON_API_URL` | Yes | Authon 서버 URL |
84
+ | `AUTHON_PUBLISHABLE_KEY` | Yes | 프로젝트 퍼블리셔블 키 |
85
+
86
+ ## 비교
87
+
88
+ | 기능 | Authon | Clerk | Auth.js |
89
+ |------|--------|-------|---------|
90
+ | 셀프 호스팅 | Yes | No | 부분적 |
91
+ | 가격 | 무료 | $25/월+ | 무료 |
92
+ | OAuth 프로바이더 | 10+ | 20+ | 80+ |
93
+ | ShadowDOM 모달 | Yes | No | No |
94
+ | MFA/패스키 | Yes | Yes | 플러그인 |
95
+ | Web3 인증 | Yes | No | No |
96
+
97
+ ## 라이선스
98
+
99
+ MIT
package/README.md CHANGED
@@ -1,103 +1,293 @@
1
+ **English** | [한국어](./README.ko.md)
2
+
1
3
  # @authon/js
2
4
 
3
- Core browser SDK for [Authon](https://authon.dev) ShadowDOM login modal, OAuth flows, and session management.
5
+ > Drop-in browser authentication SDK — self-hosted Clerk alternative, Auth0 alternative, open-source auth
6
+
7
+ [![npm version](https://img.shields.io/npm/v/@authon/js?color=6d28d9)](https://www.npmjs.com/package/@authon/js)
8
+ [![License](https://img.shields.io/badge/license-MIT-blue)](../../LICENSE)
9
+
10
+ ## Prerequisites
11
+
12
+ Before installing the SDK, create an Authon project and get your API keys:
13
+
14
+ 1. **Create a project** at [Authon Dashboard](https://authon.dev/dashboard/overview)
15
+ - Click "Create Project" and enter your app name
16
+ - Select the authentication methods you want (Email/Password, OAuth providers, etc.)
17
+
18
+ 2. **Get your API keys** from Project Settings → API Keys
19
+ - **Publishable Key** (`pk_live_...` or `pk_test_...`) — safe to use in client-side code
20
+ - **Secret Key** (`sk_live_...` or `sk_test_...`) — server-side only, never expose to clients
21
+
22
+ 3. **Configure OAuth providers** (optional) in Project Settings → OAuth
23
+ - Add Google, Apple, GitHub, etc. with their respective Client ID and Secret
24
+ - Set the redirect URL to `https://api.authon.dev/v1/auth/oauth/redirect`
25
+
26
+ > **Test vs Live keys:** Use `pk_test_...` during development. Switch to `pk_live_...` before deploying to production. Test keys use a sandbox environment with no rate limits.
4
27
 
5
28
  ## Install
6
29
 
7
30
  ```bash
8
31
  npm install @authon/js
9
- # or
10
- pnpm add @authon/js
11
32
  ```
12
33
 
13
34
  ## Quick Start
14
35
 
36
+ ```html
37
+ <!-- index.html -->
38
+ <!DOCTYPE html>
39
+ <html>
40
+ <head><title>My App</title></head>
41
+ <body>
42
+ <button id="sign-in-btn">Sign In</button>
43
+ <div id="user-info"></div>
44
+
45
+ <script type="module">
46
+ import { Authon } from '@authon/js';
47
+
48
+ const authon = new Authon('pk_live_YOUR_PUBLISHABLE_KEY', {
49
+ apiUrl: 'https://your-authon-server.com',
50
+ });
51
+
52
+ document.getElementById('sign-in-btn').addEventListener('click', () => {
53
+ authon.openSignIn();
54
+ });
55
+
56
+ authon.on('signedIn', (user) => {
57
+ document.getElementById('user-info').textContent = `Hello, ${user.email}`;
58
+ document.getElementById('sign-in-btn').style.display = 'none';
59
+ });
60
+ </script>
61
+ </body>
62
+ </html>
63
+ ```
64
+
65
+ ## Common Tasks
66
+
67
+ ### Add Google OAuth Login
68
+
15
69
  ```ts
16
70
  import { Authon } from '@authon/js';
17
71
 
18
- const authon = new Authon('pk_live_...');
72
+ const authon = new Authon('pk_live_YOUR_PUBLISHABLE_KEY', {
73
+ apiUrl: 'https://your-authon-server.com',
74
+ });
19
75
 
20
- // Open the sign-in modal
21
- await authon.openSignIn();
76
+ // Opens popup, falls back to redirect if blocked
77
+ await authon.signInWithOAuth('google');
78
+
79
+ // Force redirect mode
80
+ await authon.signInWithOAuth('google', { flowMode: 'redirect' });
81
+
82
+ // Supported providers: google, apple, github, discord, facebook,
83
+ // microsoft, kakao, naver, line, x
84
+ ```
85
+
86
+ ### Add Email/Password Auth
87
+
88
+ ```ts
89
+ import { Authon } from '@authon/js';
22
90
 
23
- // Listen for auth events
24
- authon.on('signedIn', (user) => {
25
- console.log('Signed in:', user.email);
91
+ const authon = new Authon('pk_live_YOUR_PUBLISHABLE_KEY', {
92
+ apiUrl: 'https://your-authon-server.com',
26
93
  });
27
94
 
28
- authon.on('signedOut', () => {
29
- console.log('Signed out');
95
+ // Sign up
96
+ const user = await authon.signUpWithEmail('user@example.com', 'MyP@ssw0rd', {
97
+ displayName: 'Alice',
30
98
  });
31
99
 
32
- // Email/password sign-in
33
- const user = await authon.signInWithEmail('user@example.com', 'password');
100
+ // Sign in
101
+ const user = await authon.signInWithEmail('user@example.com', 'MyP@ssw0rd');
102
+ ```
34
103
 
35
- // OAuth sign-in (uses dashboard default flow: auto | popup | redirect)
36
- await authon.signInWithOAuth('google');
104
+ ### Get Current User
37
105
 
38
- // Optional runtime override
39
- await authon.signInWithOAuth('google', { flowMode: 'redirect' });
106
+ ```ts
107
+ // Synchronous no network request
108
+ const user = authon.getUser();
109
+ // { id, email, displayName, avatarUrl, emailVerified, ... }
40
110
 
41
- // Get current user and token
42
- const currentUser = authon.getUser();
43
111
  const token = authon.getToken();
112
+ // Use token for authenticated API calls
113
+ ```
114
+
115
+ ### Open Built-in Sign-In Modal
116
+
117
+ ```ts
118
+ // ShadowDOM modal — no CSS conflicts with your app
119
+ await authon.openSignIn();
120
+ await authon.openSignUp();
121
+ ```
122
+
123
+ ### Handle Sign Out
44
124
 
45
- // Sign out
125
+ ```ts
46
126
  await authon.signOut();
47
127
  ```
48
128
 
49
- ## Configuration
129
+ ### Add Passkey (WebAuthn) Login
50
130
 
51
131
  ```ts
52
- const authon = new Authon('pk_live_...', {
53
- apiUrl: 'https://api.authon.dev', // Custom API URL
54
- mode: 'popup', // 'popup' | 'embedded'
55
- theme: 'auto', // 'light' | 'dark' | 'auto'
56
- locale: 'en', // Locale for the modal UI
57
- containerId: 'auth-container', // Container element ID (embedded mode)
58
- appearance: { // Custom branding overrides
59
- primaryColorStart: '#7c3aed',
60
- primaryColorEnd: '#4f46e5',
61
- borderRadius: 12,
62
- brandName: 'My App',
63
- },
132
+ // Register passkey (user must be signed in)
133
+ const credential = await authon.registerPasskey('My MacBook');
134
+
135
+ // Sign in with passkey
136
+ const user = await authon.authenticateWithPasskey();
137
+ ```
138
+
139
+ ### Add Web3 Wallet Login (MetaMask)
140
+
141
+ ```ts
142
+ const { message } = await authon.web3GetNonce('0xAbc...', 'evm', 'metamask', 1);
143
+ const signature = await window.ethereum.request({
144
+ method: 'personal_sign',
145
+ params: [message, '0xAbc...'],
64
146
  });
147
+ const user = await authon.web3Verify(message, signature, '0xAbc...', 'evm', 'metamask');
148
+ ```
149
+
150
+ ### Add MFA (TOTP)
151
+
152
+ ```ts
153
+ import { Authon, AuthonMfaRequiredError } from '@authon/js';
154
+
155
+ // Setup MFA (user must be signed in)
156
+ const setup = await authon.setupMfa();
157
+ document.getElementById('qr').innerHTML = setup.qrCodeSvg;
158
+ await authon.verifyMfaSetup('123456'); // code from authenticator app
159
+
160
+ // Sign in with MFA
161
+ try {
162
+ await authon.signInWithEmail('user@example.com', 'password');
163
+ } catch (err) {
164
+ if (err instanceof AuthonMfaRequiredError) {
165
+ const user = await authon.verifyMfa(err.mfaToken, '123456');
166
+ }
167
+ }
168
+ ```
169
+
170
+ ### Listen to Auth Events
171
+
172
+ ```ts
173
+ authon.on('signedIn', (user) => console.log('Signed in:', user.email));
174
+ authon.on('signedOut', () => console.log('Signed out'));
175
+ authon.on('error', (err) => console.error(err.message));
176
+ authon.on('mfaRequired', (mfaToken) => { /* show MFA dialog */ });
177
+ authon.on('tokenRefreshed', (token) => { /* update API client */ });
65
178
  ```
66
179
 
180
+ ## Environment Variables
181
+
182
+ | Variable | Required | Description |
183
+ |----------|----------|-------------|
184
+ | `AUTHON_API_URL` | Yes | Your Authon server URL (e.g. `https://your-authon-server.com`) |
185
+ | `AUTHON_PUBLISHABLE_KEY` | Yes | Project publishable key (`pk_live_...` or `pk_test_...`) |
186
+
67
187
  ## API Reference
68
188
 
69
- ### `Authon` class
70
-
71
- | Method | Returns | Description |
72
- |--------|---------|-------------|
73
- | `openSignIn()` | `Promise<void>` | Open the sign-in modal |
74
- | `openSignUp()` | `Promise<void>` | Open the sign-up modal |
75
- | `signInWithEmail(email, password)` | `Promise<AuthonUser>` | Sign in with email/password |
76
- | `signUpWithEmail(email, password, meta?)` | `Promise<AuthonUser>` | Register with email/password |
77
- | `signInWithOAuth(provider, options?)` | `Promise<void>` | Start OAuth flow (`auto`, `popup`, `redirect`) |
78
- | `signOut()` | `Promise<void>` | Sign out and clear session |
79
- | `getUser()` | `AuthonUser \| null` | Get current user |
80
- | `getToken()` | `string \| null` | Get current access token |
81
- | `on(event, listener)` | `() => void` | Subscribe to events (returns unsubscribe fn) |
82
- | `destroy()` | `void` | Clean up resources |
189
+ ### Constructor
83
190
 
84
- ### Events
191
+ ```ts
192
+ new Authon(publishableKey: string, config?: AuthonConfig)
193
+ ```
194
+
195
+ | Config Option | Type | Default | Description |
196
+ |--------------|------|---------|-------------|
197
+ | `apiUrl` | `string` | `https://api.authon.dev` | API base URL |
198
+ | `mode` | `'popup' \| 'embedded'` | `'popup'` | Modal display mode |
199
+ | `theme` | `'light' \| 'dark' \| 'auto'` | `'auto'` | UI theme |
200
+ | `locale` | `string` | `'en'` | UI locale |
201
+ | `containerId` | `string` | -- | Element ID for embedded mode |
202
+ | `appearance` | `Partial<BrandingConfig>` | -- | Override branding |
203
+
204
+ ### Auth Methods
205
+
206
+ | Method | Returns |
207
+ |--------|---------|
208
+ | `openSignIn()` | `Promise<void>` |
209
+ | `openSignUp()` | `Promise<void>` |
210
+ | `signInWithEmail(email, password)` | `Promise<AuthonUser>` |
211
+ | `signUpWithEmail(email, password, meta?)` | `Promise<AuthonUser>` |
212
+ | `signInWithOAuth(provider, options?)` | `Promise<void>` |
213
+ | `signOut()` | `Promise<void>` |
214
+ | `getUser()` | `AuthonUser \| null` |
215
+ | `getToken()` | `string \| null` |
216
+
217
+ ### Passwordless
85
218
 
86
- | Event | Payload | Description |
87
- |-------|---------|-------------|
88
- | `signedIn` | `AuthonUser` | User signed in |
89
- | `signedOut` | none | User signed out |
90
- | `tokenRefreshed` | `string` | Access token was refreshed |
91
- | `error` | `Error` | An error occurred |
219
+ | Method | Returns |
220
+ |--------|---------|
221
+ | `sendMagicLink(email)` | `Promise<void>` |
222
+ | `sendEmailOtp(email)` | `Promise<void>` |
223
+ | `verifyPasswordless({ token?, email?, code? })` | `Promise<AuthonUser>` |
92
224
 
93
- ## ShadowDOM Modal
225
+ ### Passkeys (WebAuthn)
226
+
227
+ | Method | Returns |
228
+ |--------|---------|
229
+ | `registerPasskey(name?)` | `Promise<PasskeyCredential>` |
230
+ | `authenticateWithPasskey(email?)` | `Promise<AuthonUser>` |
231
+ | `listPasskeys()` | `Promise<PasskeyCredential[]>` |
232
+ | `renamePasskey(id, name)` | `Promise<PasskeyCredential>` |
233
+ | `revokePasskey(id)` | `Promise<void>` |
234
+
235
+ ### Web3
236
+
237
+ | Method | Returns |
238
+ |--------|---------|
239
+ | `web3GetNonce(address, chain, walletType, chainId?)` | `Promise<Web3NonceResponse>` |
240
+ | `web3Verify(message, signature, address, chain, walletType)` | `Promise<AuthonUser>` |
241
+ | `listWallets()` | `Promise<Web3Wallet[]>` |
242
+ | `linkWallet(params)` | `Promise<Web3Wallet>` |
243
+ | `unlinkWallet(walletId)` | `Promise<void>` |
244
+
245
+ ### MFA
246
+
247
+ | Method | Returns |
248
+ |--------|---------|
249
+ | `setupMfa()` | `Promise<MfaSetupResponse & { qrCodeSvg }>` |
250
+ | `verifyMfaSetup(code)` | `Promise<void>` |
251
+ | `verifyMfa(mfaToken, code)` | `Promise<AuthonUser>` |
252
+ | `getMfaStatus()` | `Promise<MfaStatus>` |
253
+ | `disableMfa(code)` | `Promise<void>` |
254
+ | `regenerateBackupCodes(code)` | `Promise<string[]>` |
255
+
256
+ ### Organizations
257
+
258
+ | Method | Returns |
259
+ |--------|---------|
260
+ | `organizations.list()` | `Promise<OrganizationListResponse>` |
261
+ | `organizations.create(params)` | `Promise<AuthonOrganization>` |
262
+ | `organizations.get(orgId)` | `Promise<AuthonOrganization>` |
263
+ | `organizations.update(orgId, params)` | `Promise<AuthonOrganization>` |
264
+ | `organizations.delete(orgId)` | `Promise<void>` |
265
+ | `organizations.invite(orgId, params)` | `Promise<OrganizationInvitation>` |
266
+
267
+ ### Events
94
268
 
95
- The login modal renders inside a ShadowRoot, preventing CSS conflicts with your application. Branding (colors, logo, border radius, custom CSS) is fetched from your Authon project settings and can be overridden via the `appearance` config.
269
+ | Event | Payload |
270
+ |-------|---------|
271
+ | `signedIn` | `AuthonUser` |
272
+ | `signedOut` | -- |
273
+ | `tokenRefreshed` | `string` |
274
+ | `mfaRequired` | `string` (mfaToken) |
275
+ | `passkeyRegistered` | `PasskeyCredential` |
276
+ | `web3Connected` | `Web3Wallet` |
277
+ | `error` | `Error` |
96
278
 
97
- ## Documentation
279
+ ## Comparison
98
280
 
99
- [authon.dev/docs](https://authon.dev/docs)
281
+ | Feature | Authon | Clerk | Auth.js |
282
+ |---------|--------|-------|---------|
283
+ | Self-hosted | Yes | No | Partial |
284
+ | Pricing | Free | $25/mo+ | Free |
285
+ | OAuth providers | 10+ | 20+ | 80+ |
286
+ | ShadowDOM modal | Yes | No | No |
287
+ | MFA/Passkeys | Yes | Yes | Plugin |
288
+ | Web3 auth | Yes | No | No |
289
+ | Organizations | Yes | Yes | No |
100
290
 
101
291
  ## License
102
292
 
103
- [MIT](../../LICENSE)
293
+ MIT