@ciromaciel/auth-react 1.0.0 → 1.0.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.
Files changed (2) hide show
  1. package/README.md +102 -92
  2. package/package.json +8 -9
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Auth React
1
+ # @ciromaciel/auth-react
2
2
 
3
3
  <p align="center">
4
4
  <a href="https://www.npmjs.com/package/@ciromaciel/auth-react" target="_blank"><img src="https://img.shields.io/npm/v/@ciromaciel/auth-react.svg" alt="npm version" /></a>
@@ -6,7 +6,11 @@
6
6
  <a href="https://www.npmjs.com/package/@ciromaciel/auth-react" target="_blank"><img src="https://img.shields.io/npm/l/@ciromaciel/auth-react.svg" alt="license" /></a>
7
7
  </p>
8
8
 
9
- Auth SDK for React with JWT and JWKS.
9
+ Passwordless authentication for React: a code arrives by email, and it becomes a JWT session.
10
+
11
+ There is one way in. No password, no sign-up screen, no reset flow — the account is created and
12
+ verified the first time a code is presented. Social sign-in is available when the application
13
+ owner enables a provider.
10
14
 
11
15
  ## Installation
12
16
 
@@ -14,32 +18,28 @@ Auth SDK for React with JWT and JWKS.
14
18
  bun add @ciromaciel/auth-react
15
19
  ```
16
20
 
17
- ## Basic Usage
21
+ Peer dependencies: `react`, `react-dom`, `react-router-dom` and `zustand`. The pre-built screens
22
+ also need `@mantine/core`, `@mantine/form`, `@mantine/hooks` and `@tabler/icons-react` — all
23
+ optional if you build your own UI from the hooks.
24
+
25
+ ## Quick start
18
26
 
19
27
  ```jsx
20
- import { AuthProvider, useAuth, useSignIn, Protect, SignedIn, SignedOut, SignIn } from '@ciromaciel/auth-react'
28
+ import { AuthProvider, Protect, SignIn, SignedIn, SignedOut, SignInButton } from '@ciromaciel/auth-react'
21
29
 
22
- // 1. Wrap your app with AuthProvider
23
30
  function App() {
24
31
  return (
25
32
  <AuthProvider apiKey="your-api-key">
26
33
  <Routes>
27
- <Route
28
- path="/login"
29
- element={<SignIn />}
30
- />
31
- <Route element={<Protect />}>
32
- <Route
33
- path="/"
34
- element={<Home />}
35
- />
34
+ <Route path="/login" element={<SignIn />} />
35
+ <Route element={<Protect redirectTo="/login" />}>
36
+ <Route path="/" element={<Home />} />
36
37
  </Route>
37
38
  </Routes>
38
39
  </AuthProvider>
39
40
  )
40
41
  }
41
42
 
42
- // 2. Use control components for conditional rendering
43
43
  function Header() {
44
44
  return (
45
45
  <header>
@@ -54,116 +54,126 @@ function Header() {
54
54
  }
55
55
  ```
56
56
 
57
- ## Components
58
-
59
- ### Authentication Components
60
-
61
- | Component | Description |
62
- | --------------------- | --------------------------------------------------------------- |
63
- | `<SignIn />` | The whole way in: asks for the email, then takes the emailed code |
64
- | `<UserProfile />` | User profile management modal |
65
- | `<UserInformation />` | Flexible user details and account menu |
66
- | `<SocialButtons />` | Sign-in buttons for the providers the application enabled |
57
+ `AuthProvider` takes `apiKey` (required), `apiUrl`, `internal` and `onError`. In `internal` mode
58
+ the API key is not required — that is for same-origin applications.
67
59
 
68
- There is one screen. Sign-up, magic link, password reset and email verification
69
- were four answers to the same question — does this person control this inbox? —
70
- and three of them answered it with a URL. The code answers it with none, and the
71
- account is created, and verified, the first time one is presented.
60
+ ## Signing in
72
61
 
73
- Social sign-in is the one path that does leave for a URL, because it has to: the
74
- person goes to the provider's consent screen and comes back. `<SignIn />`
75
- renders those buttons on its own — the `socialLogin` prop defaults to `'auto'`,
76
- which shows whatever the application owner enabled in the Auth panel and nothing
77
- at all when they enabled none. An application with no provider configured
78
- renders exactly what it rendered before.
62
+ Two steps, and nothing else:
79
63
 
80
64
  ```jsx
81
- // Nothing to pass: the buttons appear when a provider is live.
82
- <SignIn />
65
+ import { useSignIn } from '@ciromaciel/auth-react'
83
66
 
84
- // Or opt out entirely, for a screen that wants the emailed code only.
85
- <SignIn socialLogin={false} />
86
- ```
67
+ const { requestCode, verifyCode, sending, verifying, error } = useSignIn()
87
68
 
88
- Building your own screen? `getSocialProviders()` lists what is live,
89
- `startSocialSignIn(provider, { redirect })` leaves for the provider, and
90
- `consumeSocialToken()` reads the token the callback leaves in the URL fragment —
91
- `AuthProvider` already calls that one for you. `startSocialLink()`,
92
- `unlinkSocialProvider()` and `getLinkedProviders()` manage the connections of an
93
- account that is already signed in.
69
+ await requestCode(email) // a code goes out by email
70
+ await verifyCode(email, code) // the code becomes a session
71
+ ```
94
72
 
95
- ### Signing in
73
+ Or use the ready-made screen:
96
74
 
97
75
  ```jsx
98
76
  <SignIn
99
- authenticatedRedirect="/" // where to send someone who already has a session
77
+ authenticatedRedirect="/" // where to send someone who already has a session
100
78
  onCodeSent={email => notify(`Code sent to ${email}`)}
101
79
  onSuccess={(user, { result, redirectHandled }) => notify(`Welcome ${user?.email}`)}
102
- onError={error => notify(error.message)} {/* error.code traz o identificador estável */}
80
+ onError={error => notify(error.message)} // error.code carries the stable identifier
103
81
  />
104
82
  ```
105
83
 
106
- - `onSuccess` receives the **user** first; the raw API response is `result`.
107
- - `redirectHandled` is `true` when an OAuth `?redirect=` was already applied — the SDK executes it before calling you, so it is information, not a duty.
108
- - A wrong code fails with `error.details.attemptsLeft`; five wrong tries destroy the request and the person asks for a new code.
109
- - Nothing here builds a callback URL. There is no destination to validate, and none to hijack.
84
+ - `onSuccess` receives the **user** first; the raw API response is `result`.
85
+ - `redirectHandled` is `true` when a `?redirect=` in the URL was already applied. The component
86
+ honours it by default, validating the destination against the API origin and the current one;
87
+ `redirectOrigins` adds domains and `handleRedirect={false}` hands control back to the app.
88
+ - A wrong code fails with `error.details.attemptsLeft`. Five wrong tries destroy the request and
89
+ the person asks for a new code.
110
90
 
111
- ### Control Components
91
+ ### Social sign-in
92
+
93
+ `<SignIn />` renders the provider buttons on its own: `socialLogin` defaults to `'auto'`, which
94
+ shows whatever the application owner enabled and nothing at all when they enabled none.
95
+
96
+ ```jsx
97
+ <SignIn /> {/* buttons appear when a provider is live */}
98
+ <SignIn socialLogin={false} /> {/* emailed code only */}
99
+ ```
100
+
101
+ Building your own screen? `getSocialProviders()` lists what is live,
102
+ `startSocialSignIn(provider, { redirect })` leaves for the provider, and `consumeSocialToken()`
103
+ reads the token the callback leaves in the URL fragment — `AuthProvider` already calls that one
104
+ for you. `startSocialLink()`, `unlinkSocialProvider()` and `getLinkedProviders()` manage the
105
+ connections of an account that is already signed in.
106
+
107
+ ## API
108
+
109
+ ### Components
110
+
111
+ | Component | Description |
112
+ | ------------------------- | ------------------------------------------------------------ |
113
+ | `<SignIn />` | The whole way in: asks for the email, then takes the code |
114
+ | `<UserProfile />` | User profile management modal |
115
+ | `<UserInformation />` | User details and account menu |
116
+ | `<SocialButtons />` | Sign-in buttons for the providers the application enabled |
117
+ | `<AuthCard />` | The card shell the screens are built on |
118
+ | `<Wordmark />` | Application wordmark |
119
+
120
+ ### Routing
121
+
122
+ | Component | Description |
123
+ | ---------------- | ------------------------------------------------------------- |
124
+ | `<Protect />` | Route wrapper; redirects to `redirectTo` without a session |
125
+ | `<GuestOnly />` | The counterpart: keeps a signed-in person off the login screen |
126
+
127
+ ### Conditional rendering
112
128
 
113
129
  | Component | Description |
114
130
  | --------------- | -------------------------------------------- |
115
131
  | `<SignedIn>` | Renders children only when authenticated |
116
132
  | `<SignedOut>` | Renders children only when NOT authenticated |
117
133
  | `<AuthLoading>` | Renders children while auth is loading |
118
- | `<AuthLoaded>` | Renders children when auth has loaded |
119
- | `<Protect />` | Protected route wrapper |
134
+ | `<AuthLoaded>` | Renders children once auth has loaded |
120
135
 
121
- ### Unstyled Buttons
136
+ ### Unstyled buttons
122
137
 
123
138
  | Component | Description |
124
139
  | ------------------- | ------------------------- |
125
140
  | `<SignInButton />` | Navigates to sign-in page |
126
141
  | `<SignOutButton />` | Signs out the user |
127
142
 
128
- ## Hooks
143
+ ### Hooks
129
144
 
130
145
  ```jsx
131
- const { user, loading, error, isAuthenticated } = useAuth()
132
- const { user, updateProfile } = useUser()
133
- const { requestCode, verifyCode, sending, verifying } = useSignIn()
146
+ const { user, loading, error, isAuthenticated, requestCode, verifyCode, signOut } = useAuth()
147
+ const { user, updateProfile, loadingUpdateProfile } = useUser()
148
+ const { requestCode, verifyCode, sending, verifying, error } = useSignIn()
149
+ const { getSession, user, setUser } = useSession()
150
+ const { sessions, listSessions, revokeSession, revokeOtherSessions } = useSessions()
151
+ const loadingStates = useAuthLoading()
152
+ const impersonation = useImpersonation() // the borrowed session, or null
153
+ const logo = useApplicationLogo()
134
154
  const signOut = useSignOut()
135
-
136
- // The two steps, and nothing else:
137
- await requestCode(email) // a code goes out by email
138
- await verifyCode(email, code) // the code becomes a session
155
+ const checkToken = useCheckToken()
139
156
  ```
140
157
 
158
+ ### Direct SDK calls
159
+
160
+ For code outside React, the HTTP layer is exported too: `configure`, `requestCode`, `verifyCode`,
161
+ `pollCode`, `signOut`, `refreshToken`, `getSession`, `listSessions`, `revokeSession`,
162
+ `revokeOtherSessions`, `updateProfile`, `getApplicationInfo`, `isAuthenticated`, `getCurrentUser`,
163
+ `decodeJWT`, `setStoredToken`, and the social helpers listed above.
164
+
141
165
  ## Features
142
166
 
143
- - ✅ **Social sign-in** - Google, with the application owner's own credentials
144
- - ✅ **JWT Tokens** - Secure token-based authentication
145
- - ✅ **JWKS** - Signature verification with `/.well-known/jwks.json`
146
- - ✅ **Auto refresh** - Tokens renewed automatically
147
- - ✅ **One way in** - An emailed code, for people and agents alike; no password to leak
148
- - ✅ **Cross-tab sync** - Synchronized state across tabs
149
- - ✅ **Route protection** - Protected routes automatically
150
- - ✅ **Control components** - Clerk-style conditional rendering
151
- - ✅ **SSR friendly** - Server-side rendering compatible
152
-
153
- ## Removed in 4.0.0
154
-
155
- Along with the password, magic link, reset and verification flows:
156
-
157
- | Removed | Use instead |
158
- | ------------------------------------------------------------------ | ---------------------------------------- |
159
- | `signUp`, `signIn`, `sendMagicLink`, `verifyMagicLink` | `requestCode` + `verifyCode` |
160
- | `forgotPassword`, `resetPassword`, `changePassword` | — there is no password |
161
- | `verifyEmail`, `resendVerification` | — presenting the code already verifies |
162
- | `changeEmail` | the email is the credential |
163
- | `socialRedirect` | never existed under that name — social sign-in ships as `startSocialSignIn` |
164
- | `<SignUp>`, `<MagicLink>`, `<MagicLinkCallback>` | `<SignIn>` |
165
- | `<ForgotPassword>`, `<ResetPassword>`, `<VerifyEmail>` | `<SignIn>` |
166
- | `<SignUpButton>` | `<SignInButton>` |
167
- | `useSignUp`, `useMagicLink`, `usePasswordReset` | `useSignIn` |
168
- | `useEmailVerification` | `useSignIn` |
169
- | `SignInForm`, `AccountModal`, `ProtectedRoute`, `useProfile` | `SignIn`, `UserProfile`, `Protect`, `useUser` |
167
+ - **Passwordless** — an emailed code, for people and agents alike; no password to leak
168
+ - **JWT sessions** with automatic refresh
169
+ - **JWKS** signature verification via `/.well-known/jwks.json`
170
+ - **Cross-tab sync** — sign out in one tab, every tab follows
171
+ - **Route protection** through `<Protect />` and `<GuestOnly />`
172
+ - **SSR friendly**
173
+
174
+ ## Links
175
+
176
+ - [Website](https://ciromaciel.click)
177
+ - [Package on npm](https://www.npmjs.com/package/@ciromaciel/auth-react)
178
+
179
+ MIT © [Ciro Cesar Maciel](https://ciromaciel.click)
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@ciromaciel/auth-react",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
- "description": "Auth SDK for React with JWT, Mantine UI components, and full authentication flows",
5
+ "description": "Auth SDK for React: JWT sessions, passwordless sign-in, and ready-made Mantine screens.",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.esm.js",
8
8
  "types": "dist/index.d.ts",
@@ -68,11 +68,6 @@
68
68
  "semantic-release": "^24.2.5",
69
69
  "zustand": "^5.0.9"
70
70
  },
71
- "repository": {
72
- "type": "git",
73
- "url": "https://github.com/riligar-infrastructure/auth",
74
- "directory": "packages/auth-react"
75
- },
76
71
  "publishConfig": {
77
72
  "access": "public"
78
73
  },
@@ -83,6 +78,10 @@
83
78
  "sdk",
84
79
  "riligar"
85
80
  ],
86
- "author": "Riligar",
87
- "license": "Unlicense"
81
+ "author": "Ciro Cesar Maciel <maciel.ciro@icloud.com> (https://ciromaciel.click)",
82
+ "license": "MIT",
83
+ "homepage": "https://ciromaciel.click",
84
+ "bugs": {
85
+ "url": "https://ciromaciel.click"
86
+ }
88
87
  }