@main12/auth-login 0.1.1 → 0.1.3

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.md CHANGED
@@ -1,218 +1,320 @@
1
- # Payload Plugin Template
1
+ # @main12/auth-login
2
2
 
3
- A template repo to create a [Payload CMS](https://payloadcms.com) plugin.
3
+ **Payload CMS authentication plugin** — login, signup, OTP, forgot password, branded emails, and "Powered by Main 12" footer. Install once, done.
4
4
 
5
- Payload is built with a robust infrastructure intended to support Plugins with ease. This provides a simple, modular, and reusable way for developers to extend the core capabilities of Payload.
6
-
7
- To build your own Payload plugin, all you need is:
5
+ ```ts
6
+ // payload.config.ts
7
+ import { authLoginPlugin } from '@main12/auth-login'
8
8
 
9
- - An understanding of the basic Payload concepts
10
- - And some JavaScript/Typescript experience
9
+ plugins: [
10
+ authLoginPlugin({
11
+ projectName: 'My SaaS',
12
+ domain: 'https://myapp.com',
13
+ logo: 'https://myapp.com/logo.png', // shown in all auth pages + emails
14
+ style: 'hero-ui', // 'tailwind' (default) | 'hero-ui'
15
+ }),
16
+ ]
17
+ ```
11
18
 
12
- ## Background
19
+ ---
13
20
 
14
- Here is a short recap on how to integrate plugins with Payload, to learn more visit the [plugin overview page](https://payloadcms.com/docs/plugins/overview).
21
+ ## Features
15
22
 
16
- ### How to install a plugin
23
+ - **5 auth pages** — login (multi-step), signup, forgot password, verify OTP, set password
24
+ - **Multi-style** — `tailwind` (zero UI deps) or `hero-ui` (HeroUI + framer-motion). Set once in config
25
+ - **5 API endpoints** — `check-email`, `otp/send`, `otp/verify`, `set-password`, `signup`
26
+ - **OTP engine** — SHA-256 hashing + `timingSafeEqual` comparison, 10-min expiry, 3 attempts
27
+ - **Email templates** — welcome, OTP login, password reset, password changed (EN/ES)
28
+ - **Powered by Main 12** — bundled inline SVG, linked to main12.com by default (URL overridable)
29
+ - **Global logo** — pass once in plugin config, automatically shown on all pages and email headers
30
+ - **Zero runtime deps** (Tailwind mode) — Next.js + React are peer dependencies
17
31
 
18
- To install any plugin, simply add it to your payload.config() in the Plugin array.
32
+ ---
19
33
 
20
- ```ts
21
- import myPlugin from 'my-plugin'
34
+ ## Installation
22
35
 
23
- export const config = buildConfig({
24
- plugins: [
25
- // You can pass options to the plugin
26
- myPlugin({
27
- enabled: true,
28
- }),
29
- ],
30
- })
36
+ ```bash
37
+ pnpm add @main12/auth-login
31
38
  ```
32
39
 
33
- ### Initialization
34
-
35
- The initialization process goes in the following order:
40
+ ### Tailwind mode (default, zero UI deps — also ShadCN compatible)
36
41
 
37
- 1. Incoming config is validated
38
- 2. **Plugins execute**
39
- 3. Default options are integrated
40
- 4. Sanitization cleans and validates data
41
- 5. Final config gets initialized
42
+ No extra dependencies needed. The Tailwind style uses standard utility classes that work in any Tailwind project, including ShadCN-based ones.
42
43
 
43
- ## Building the Plugin
44
+ ### HeroUI mode
44
45
 
45
- When you build a plugin, you are purely building a feature for your project and then abstracting it outside of the project.
46
-
47
- ### Template Files
46
+ ```bash
47
+ pnpm add @heroui/react framer-motion @iconify/react
48
+ ```
48
49
 
49
- In the Payload [plugin template](https://github.com/payloadcms/payload/tree/main/templates/plugin), you will see a common file structure that is used across all plugins:
50
+ ---
50
51
 
51
- 1. root folder
52
- 2. /src folder
53
- 3. /dev folder
52
+ ## Quick Start
54
53
 
55
- #### Root
54
+ ### 1. Add the plugin + Users collection to your Payload config
56
55
 
57
- In the root folder, you will see various files that relate to the configuration of the plugin. We set up our environment in a similar manner in Payload core and across other projects, so hopefully these will look familiar:
56
+ ```ts
57
+ import { authLoginPlugin } from '@main12/auth-login'
58
+
59
+ export default buildConfig({
60
+ collections: [
61
+ {
62
+ slug: 'users',
63
+ auth: { tokenExpiration: 7200, verify: false, maxLoginAttempts: 5 },
64
+ fields: [
65
+ { name: 'name', type: 'text' },
66
+ // OTP fields required by the plugin:
67
+ { name: 'otpHash', type: 'text', admin: { hidden: true } },
68
+ { name: 'otpAttempts', type: 'number', admin: { hidden: true } },
69
+ { name: 'otpExpiresAt', type: 'text', admin: { hidden: true } },
70
+ ],
71
+ },
72
+ ],
73
+ plugins: [
74
+ authLoginPlugin({
75
+ projectName: 'My App',
76
+ domain: 'https://myapp.com',
77
+ logo: '/logo.png', // shown automatically on all auth pages
78
+ style: 'hero-ui', // or 'tailwind'
79
+ }),
80
+ ],
81
+ })
82
+ ```
58
83
 
59
- - **README**.md\* - This contains instructions on how to use the template. When you are ready, update this to contain instructions on how to use your Plugin.
60
- - **package**.json\* - Contains necessary scripts and dependencies. Overwrite the metadata in this file to describe your Plugin.
61
- - .**eslint**.config.js - Eslint configuration for reporting on problematic patterns.
62
- - .**gitignore** - List specific untracked files to omit from Git.
63
- - .**prettierrc**.json - Configuration for Prettier code formatting.
64
- - **tsconfig**.json - Configures the compiler options for TypeScript
65
- - .**swcrc** - Configuration for SWC, a fast compiler that transpiles and bundles TypeScript.
66
- - **vitest**.config.js - Config file for Vitest, defining how tests are run and how modules are resolved
84
+ ### 2. Add auth pages to your app
67
85
 
68
- **IMPORTANT\***: You will need to modify these files.
86
+ Create one-line route files under `src/app/(frontend)/(auth)/`:
69
87
 
70
- #### Dev
88
+ ```tsx
89
+ // login/page.tsx
90
+ export { LoginPage as default } from '@main12/auth-login/client'
71
91
 
72
- In the dev folder, you’ll find a basic payload project, created with `npx create-payload-app` and the blank template.
92
+ // signup/page.tsx
93
+ export { SignupPage as default } from '@main12/auth-login/client'
73
94
 
74
- **IMPORTANT**: Make a copy of the `.env.example` file and rename it to `.env`. Update the `DATABASE_URL` to match the database you are using and your plugin name. Update `PAYLOAD_SECRET` to a unique string.
75
- **You will not be able to run `pnpm/yarn dev` until you have created this `.env` file.**
95
+ // forgot-password/page.tsx
96
+ export { ForgotPasswordPage as default } from '@main12/auth-login/client'
76
97
 
77
- `myPlugin` has already been added to the `payload.config()` file in this project.
98
+ // verify-otp/page.tsx
99
+ export { VerifyOtpPage as default } from '@main12/auth-login/client'
78
100
 
79
- ```ts
80
- plugins: [
81
- myPlugin({
82
- collections: {
83
- posts: true,
84
- },
85
- }),
86
- ]
101
+ // set-password/page.tsx
102
+ export { SetPasswordPage as default } from '@main12/auth-login/client'
87
103
  ```
88
104
 
89
- Later when you rename the plugin or add additional options, **make sure to update it here**.
105
+ The logo is already handled — no need to pass it. The plugin reads it from the global config.
90
106
 
91
- You may wish to add collections or expand the test project depending on the purpose of your plugin. Just make sure to keep this dev environment as simplified as possible - users should be able to install your plugin without additional configuration required.
107
+ ### 3. Wire up the login action
92
108
 
93
- When you’re ready to start development, initiate the project with `pnpm/npm/yarn dev` and pull up [http://localhost:3000](http://localhost:3000) in your browser.
109
+ ```tsx
110
+ // login/page.tsx — override with your Payload login function:
111
+ 'use client'
112
+ import { LoginPage } from '@main12/auth-login/client'
113
+ import { useAuth } from '@/providers/Auth'
94
114
 
95
- #### Src
115
+ export default function Page() {
116
+ const { login } = useAuth()
117
+ return <LoginPage onPasswordLogin={login} redirectTo="/dashboard" />
118
+ }
119
+ ```
96
120
 
97
- Now that we have our environment setup and we have a dev project ready to - it’s time to build the plugin!
121
+ ### 4. That's it — visit `/login`
98
122
 
99
- **index.ts**
123
+ ---
100
124
 
101
- The essence of a Payload plugin is simply to extend the payload config - and that is exactly what we are doing in this file.
125
+ ## Configuration Options
102
126
 
103
127
  ```ts
104
- export const myPlugin =
105
- (pluginOptions: MyPluginConfig) =>
106
- (config: Config): Config => {
107
- // do cool stuff with the config here
108
-
109
- return config
110
- }
128
+ authLoginPlugin({
129
+ // === Branding ===
130
+ projectName: 'My App', // Used in email subjects and footers
131
+ contactEmail: 'hi@myapp.com', // Email footer contact
132
+ domain: 'https://myapp.com', // Links in emails
133
+ logo: '/logo.png', // Shown on all auth pages + email headers
134
+
135
+ // === Style ===
136
+ style: 'tailwind', // 'tailwind' (default) | 'hero-ui'
137
+
138
+ // === Enable/Disable ===
139
+ enabled: true, // Set false to disable the plugin
140
+ })
111
141
  ```
112
142
 
113
- First, we receive the existing payload config along with any plugin options.
143
+ ### Per-page overrides
144
+
145
+ Each page component also accepts these props for project-specific customization:
114
146
 
115
- From here, you can extend the config as you wish.
147
+ ```ts
148
+ <LoginPage
149
+ logo={<AppLogo width={180} />} // Override global logo (optional)
150
+ onPasswordLogin={login} // Required — Payload's login function
151
+ redirectTo="/dashboard" // Where to go after login
152
+ showGoogleOAuth={true} // Show "Continue with Google" button
153
+ signupUrl="/signup" // Link to signup page
154
+ poweredBy={{ // Powered by logo config
155
+ enabled: true,
156
+ logoUrl: '/custom.png', // Override default Main12 logo
157
+ linkUrl: 'https://your-site.com',
158
+ }}
159
+ />
160
+ ```
116
161
 
117
- Finally, you return the config and that is it!
162
+ ---
118
163
 
119
- ##### Spread Syntax
164
+ ## Building Custom Auth Pages
120
165
 
121
- Spread syntax (or the spread operator) is a feature in JavaScript that uses the dot notation **(...)** to spread elements from arrays, strings, or objects into various contexts.
166
+ You can build your own UI while reusing the plugin's hooks, services, and endpoints.
122
167
 
123
- We are going to use spread syntax to allow us to add data to existing arrays without losing the existing data. It is crucial to spread the existing data correctly – else this can cause adverse behavior and conflicts with Payload config and other plugins.
168
+ ### Custom login with your own components
124
169
 
125
- Let’s say you want to build a plugin that adds a new collection:
170
+ ```tsx
171
+ 'use client'
172
+ import { useLoginFlow } from '@main12/auth-login/client'
173
+ import { Button, Input } from '@heroui/react' // or shadcn, or plain HTML
174
+ import { useAuth } from '@/providers/Auth'
126
175
 
127
- ```ts
128
- config.collections = [
129
- ...(config.collections || []),
130
- // Add additional collections here
131
- ]
176
+ export default function MyCustomLogin() {
177
+ const { login } = useAuth()
178
+ const {
179
+ step, email, password, error, isLoading, showPassword,
180
+ setEmail, setPassword, setShowPassword,
181
+ handleEmailSubmit, handlePasswordSubmit, handleSendOtp, handleEditEmail,
182
+ } = useLoginFlow({
183
+ redirectTo: '/dashboard',
184
+ onPasswordLogin: login,
185
+ })
186
+
187
+ return (
188
+ <div className="min-h-screen flex items-center justify-center">
189
+ <div className="w-full max-w-md p-8 bg-white rounded-2xl shadow-xl">
190
+ {step === 'email' && (
191
+ <form onSubmit={handleEmailSubmit}>
192
+ <Input type="email" label="Email" value={email} onValueChange={setEmail} />
193
+ <Button type="submit" isLoading={isLoading}>Continue</Button>
194
+ </form>
195
+ )}
196
+ {step === 'password' && (
197
+ <form onSubmit={handlePasswordSubmit}>
198
+ <p>Signing in as {email} <button onClick={handleEditEmail}>Edit</button></p>
199
+ <Input type="password" label="Password" value={password} onValueChange={setPassword} />
200
+ <Button type="submit" isLoading={isLoading}>Sign In</Button>
201
+ </form>
202
+ )}
203
+ {step === 'otp-prompt' && (
204
+ <>
205
+ <p>{email} <button onClick={handleEditEmail}>Edit</button></p>
206
+ <Button onPress={handleSendOtp} isLoading={isLoading}>Send Code</Button>
207
+ </>
208
+ )}
209
+ </div>
210
+ </div>
211
+ )
212
+ }
132
213
  ```
133
214
 
134
- First we spread the `config.collections` to ensure that we don’t lose the existing collections, then you can add any additional collections just as you would in a regular payload config.
215
+ ### Custom email templates
135
216
 
136
- This same logic is applied to other properties like admin, hooks, globals:
217
+ Override individual email translations or entire template functions:
137
218
 
138
219
  ```ts
139
- config.globals = [
140
- ...(config.globals || []),
141
- // Add additional globals here
142
- ]
220
+ import { getEmailTranslations } from '@main12/auth-login/rsc'
143
221
 
144
- config.hooks = {
145
- ...(incomingConfig.hooks || {}),
146
- // Add additional hooks here
222
+ // Option 1: Deep-merge translations
223
+ const myTranslations = getEmailTranslations('en')
224
+ myTranslations.welcome.subject = 'Welcome to My SaaS! 🚀'
225
+ myTranslations.otp.purposeLogin = 'Use this code to access your dashboard:'
226
+
227
+ // Option 2: Import template generators and wrap them
228
+ import { generateWelcomeEmail, generateOtpEmail } from '@main12/auth-login/rsc'
229
+
230
+ function myWelcomeEmail(params) {
231
+ const base = generateWelcomeEmail(params)
232
+ return {
233
+ ...base,
234
+ html: base.html.replace('Get Started', 'Launch Dashboard'),
235
+ }
147
236
  }
237
+
238
+ // Use in your Payload hooks or custom endpoints
239
+ await payload.sendEmail({
240
+ to: user.email,
241
+ subject: myWelcomeEmail({ userName: user.name }).subject,
242
+ html: myWelcomeEmail({ userName: user.name }).html,
243
+ })
148
244
  ```
149
245
 
150
- Some properties will be slightly different to extend, for instance the onInit property:
246
+ ---
151
247
 
152
- ```ts
153
- import { onInitExtension } from './onInitExtension' // example file
248
+ ## Exported Hooks & Services
154
249
 
155
- config.onInit = async (payload) => {
156
- if (incomingConfig.onInit) await incomingConfig.onInit(payload)
157
- // Add additional onInit code by defining an onInitExtension function
158
- onInitExtension(pluginOptions, payload)
159
- }
160
- ```
250
+ | Hook / Service | Type | Purpose |
251
+ |---------------|------|---------|
252
+ | `useLoginFlow` | Hook | Multi-step login state machine (email → password/OTP) |
253
+ | `useVerifyOtpFlow` | Hook | OTP input, verify, resend with cooldown |
254
+ | `useForgotPasswordFlow` | Hook | Email → check → send OTP |
255
+ | `useSetPasswordFlow` | Hook | Set password with strength indicator |
256
+ | `checkEmail(email)` | Service | Check if user exists and has password |
257
+ | `sendOtp(email, purpose)` | Service | Send OTP to email |
258
+ | `verifyOtp(email, otp)` | Service | Verify OTP code |
259
+ | `setUserPassword(pw, confirm)` | Service | Set/update password |
260
+ | `signup(name, email)` | Service | Create new user |
261
+ | `initiateGoogleLogin(redirect)` | Service | Redirect to Google OAuth |
161
262
 
162
- If you wish to add to the onInit, you must include the **async/await**. We don’t use spread syntax in this case, instead you must await the existing `onInit` before running additional functionality.
263
+ ---
163
264
 
164
- In the template, we have stubbed out some addition `onInit` actions that seeds in a document to the `plugin-collection`, you can use this as a base point to add more actions - and if not needed, feel free to delete it.
265
+ ## API Endpoints
165
266
 
166
- ##### Types.ts
267
+ Registered automatically by the plugin:
167
268
 
168
- If your plugin has options, you should define and provide types for these options.
269
+ | Method | Path | Description |
270
+ |--------|------|-------------|
271
+ | POST | `/api/auth/check-email` | Check if email is registered |
272
+ | POST | `/api/auth/otp/send` | Generate + send OTP via Payload email adapter |
273
+ | POST | `/api/auth/otp/verify` | Verify OTP + login (sets httpOnly cookie) |
274
+ | POST | `/api/auth/set-password` | Set/update password |
275
+ | POST | `/api/auth/signup` | Create account + send welcome email |
169
276
 
170
- ```ts
171
- export type MyPluginConfig = {
172
- /**
173
- * List of collections to add a custom field
174
- */
175
- collections?: Partial<Record<CollectionSlug, true>>
176
- /**
177
- * Disable the plugin
178
- */
179
- disabled?: boolean
180
- }
181
- ```
277
+ ---
182
278
 
183
- If possible, include JSDoc comments to describe the options and their types. This allows a developer to see details about the options in their editor.
279
+ ## ShadCN Compatibility
184
280
 
185
- ##### Testing
281
+ The `tailwind` style uses standard Tailwind utility classes — it works in ShadCN projects out of the box. If you want ShadCN components instead of plain HTML:
186
282
 
187
- Having a test suite for your plugin is essential to ensure quality and stability. **Vitest** is a fast, modern testing framework that works seamlessly with Vite and supports TypeScript out of the box.
283
+ 1. Follow the [Custom Auth Pages](#building-custom-auth-pages) guide above
284
+ 2. Import `useLoginFlow`, `useVerifyOtpFlow`, etc. from the plugin
285
+ 3. Use your ShadCN `<Button>`, `<Input>`, `<Card>` components with the same hook values
188
286
 
189
- Vitest organizes tests into test suites and cases, similar to other testing frameworks. We recommend creating individual tests based on the expected behavior of your plugin from start to finish.
287
+ No need for a separate `style: 'shadcn'` — the Tailwind style already renders compatible markup, and custom pages give you full ShadCN component control.
190
288
 
191
- Writing tests with Vitest is very straightforward, and you can learn more about how it works in the [Vitest documentation.](https://vitest.dev/)
289
+ ---
192
290
 
193
- For this template, we stubbed out `int.spec.ts` in the `dev` folder where you can write your tests.
291
+ ## Dev Testing
194
292
 
195
- ```ts
196
- describe('Plugin tests', () => {
197
- // Create tests to ensure expected behavior from the plugin
198
- it('some condition that must be met', () => {
199
- // Write your test logic here
200
- expect(...)
201
- })
202
- })
293
+ This repo ships with a dev harness. To test locally:
294
+
295
+ ```bash
296
+ git clone https://github.com/MAIN-12/auth-login-plugin.git
297
+ cd auth-login-plugin
298
+ pnpm install
299
+ pnpm dev
203
300
  ```
204
301
 
205
- ## Best practices
302
+ Visit `http://localhost:3000/login` — all 5 auth pages wired with SQLite.
303
+
304
+ ---
305
+
306
+ ## Requirements
206
307
 
207
- With this tutorial and the plugin template, you should have everything you need to start building your own plugin.
208
- In addition to the setup, here are other best practices aim we follow:
308
+ | Dependency | Version | Required |
309
+ |------------|---------|----------|
310
+ | Payload CMS | `^3.82.0` | ✅ |
311
+ | Next.js | `^16.0.0` | ✅ |
312
+ | React | `^19.0.0` | ✅ |
313
+ | HeroUI | `^2.x` | Only for `style: 'hero-ui'` |
314
+ | Framer Motion | `^12.x` | Only for `style: 'hero-ui'` |
209
315
 
210
- - **Providing an enable / disable option:** For a better user experience, provide a way to disable the plugin without uninstalling it. This is especially important if your plugin adds additional webpack aliases, this will allow you to still let the webpack run to prevent errors.
211
- - **Include tests in your GitHub CI workflow**: If you’ve configured tests for your package, integrate them into your workflow to run the tests each time you commit to the plugin repository. Learn more about [how to configure tests into your GitHub CI workflow.](https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs)
212
- - **Publish your finished plugin to NPM**: The best way to share and allow others to use your plugin once it is complete is to publish an NPM package. This process is straightforward and well documented, find out more [creating and publishing a NPM package here.](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages/).
213
- - **Add payload-plugin topic tag**: Apply the tag **payload-plugin **to your GitHub repository. This will boost the visibility of your plugin and ensure it gets listed with [existing payload plugins](https://github.com/topics/payload-plugin).
214
- - **Use [Semantic Versioning](https://semver.org/) (SemVar)** - With the SemVar system you release version numbers that reflect the nature of changes (major, minor, patch). Ensure all major versions reference their Payload compatibility.
316
+ ---
215
317
 
216
- # Questions
318
+ ## License
217
319
 
218
- Please contact [Payload](mailto:dev@payloadcms.com) with any questions about using this plugin template.
320
+ MIT © Main 12
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  export interface AuthLayoutConfig {
3
- logo: React.ReactNode;
3
+ /** Logo as a React node. Falls back to pluginConfig.logoUrl if not provided. */
4
+ logo?: React.ReactNode;
4
5
  title?: string;
5
6
  subtitle?: string;
6
7
  poweredBy?: {
@@ -3,7 +3,19 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React from 'react';
4
4
  import { Card, CardContent, CardFooter } from './ui/index.js';
5
5
  import { PoweredBy } from './PoweredBy.js';
6
+ import { pluginConfig } from '../config.js';
7
+ function DefaultLogo() {
8
+ if (!pluginConfig.logoUrl) return null;
9
+ return /*#__PURE__*/ _jsx("img", {
10
+ src: pluginConfig.logoUrl,
11
+ alt: "",
12
+ width: 180,
13
+ height: 42,
14
+ className: "object-contain"
15
+ });
16
+ }
6
17
  export const AuthLayout = ({ children, logo, title, subtitle, footer, poweredBy, cardClassName = '', backgroundClass = 'bg-white md:bg-[#191919]' })=>{
18
+ const displayLogo = logo || /*#__PURE__*/ _jsx(DefaultLogo, {});
7
19
  return /*#__PURE__*/ _jsx("main", {
8
20
  className: `flex flex-col min-h-screen ${backgroundClass}`,
9
21
  children: /*#__PURE__*/ _jsx("div", {
@@ -14,12 +26,12 @@ export const AuthLayout = ({ children, logo, title, subtitle, footer, poweredBy,
14
26
  /*#__PURE__*/ _jsxs(Card, {
15
27
  className: cardClassName,
16
28
  children: [
17
- (logo || title) && /*#__PURE__*/ _jsxs("div", {
29
+ (displayLogo || title) && /*#__PURE__*/ _jsxs("div", {
18
30
  className: "flex flex-col items-center gap-2 pt-6 pb-2 px-6",
19
31
  children: [
20
- logo && /*#__PURE__*/ _jsx("div", {
32
+ displayLogo && /*#__PURE__*/ _jsx("div", {
21
33
  className: "flex justify-center mb-2",
22
- children: logo
34
+ children: displayLogo
23
35
  }),
24
36
  title && /*#__PURE__*/ _jsx("h1", {
25
37
  className: "text-xl font-semibold text-gray-900 text-center",
package/dist/config.d.ts CHANGED
@@ -5,4 +5,5 @@
5
5
  export type AuthStyle = 'tailwind' | 'hero-ui';
6
6
  export declare const pluginConfig: {
7
7
  style: AuthStyle;
8
+ logoUrl?: string;
8
9
  };
package/dist/index.d.ts CHANGED
@@ -7,6 +7,8 @@ export interface AuthLoginPluginOptions {
7
7
  domain?: string;
8
8
  /** UI style for auth pages: 'tailwind' (default) or 'hero-ui' */
9
9
  style?: AuthStyle;
10
+ /** Logo shown in all auth pages and email headers. Can be a URL string. */
11
+ logo?: string;
10
12
  }
11
13
  export declare const authLoginPlugin: (options?: AuthLoginPluginOptions) => (config: Config) => Config;
12
14
  export { pluginConfig };
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ export const authLoginPlugin = (options = {})=>(config)=>{
4
4
  if (options.enabled === false) return config;
5
5
  // Set global style config — all page components read this at render time
6
6
  pluginConfig.style = options.style || 'tailwind';
7
+ pluginConfig.logoUrl = options.logo;
7
8
  // Register auth API endpoints
8
9
  config.endpoints = [
9
10
  ...config.endpoints || [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@main12/auth-login",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Reusable Payload CMS auth plugin — login, signup, OTP, forgot password, branded emails, Powered by Main12",
5
5
  "license": "MIT",
6
6
  "type": "module",