payload-auth 1.0.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.
Files changed (200) hide show
  1. package/LICENSE.md +17 -0
  2. package/dist/authjs/index.d.ts +1 -0
  3. package/dist/authjs/index.js +3 -0
  4. package/dist/authjs/index.js.map +1 -0
  5. package/dist/better-auth/adapter/dev/bin/run.d.ts +1 -0
  6. package/dist/better-auth/adapter/dev/bin/run.js +64 -0
  7. package/dist/better-auth/adapter/dev/bin/run.js.map +1 -0
  8. package/dist/better-auth/adapter/dev/bin/schema.d.ts +22 -0
  9. package/dist/better-auth/adapter/dev/bin/schema.js +160 -0
  10. package/dist/better-auth/adapter/dev/bin/schema.js.map +1 -0
  11. package/dist/better-auth/adapter/dev/collections.d.ts +3 -0
  12. package/dist/better-auth/adapter/dev/collections.js +212 -0
  13. package/dist/better-auth/adapter/dev/collections.js.map +1 -0
  14. package/dist/better-auth/adapter/dev/index.d.ts +3 -0
  15. package/dist/better-auth/adapter/dev/index.js +168 -0
  16. package/dist/better-auth/adapter/dev/index.js.map +1 -0
  17. package/dist/better-auth/adapter/generate-schema/generate-schema-builder.d.ts +23 -0
  18. package/dist/better-auth/adapter/generate-schema/generate-schema-builder.js +326 -0
  19. package/dist/better-auth/adapter/generate-schema/generate-schema-builder.js.map +1 -0
  20. package/dist/better-auth/adapter/generate-schema/get-payload-schema.d.ts +1 -0
  21. package/dist/better-auth/adapter/generate-schema/get-payload-schema.js +23 -0
  22. package/dist/better-auth/adapter/generate-schema/get-payload-schema.js.map +1 -0
  23. package/dist/better-auth/adapter/generate-schema/index.d.ts +4 -0
  24. package/dist/better-auth/adapter/generate-schema/index.js +19 -0
  25. package/dist/better-auth/adapter/generate-schema/index.js.map +1 -0
  26. package/dist/better-auth/adapter/generate-schema/utils.d.ts +2 -0
  27. package/dist/better-auth/adapter/generate-schema/utils.js +20 -0
  28. package/dist/better-auth/adapter/generate-schema/utils.js.map +1 -0
  29. package/dist/better-auth/adapter/index.d.ts +5 -0
  30. package/dist/better-auth/adapter/index.js +578 -0
  31. package/dist/better-auth/adapter/index.js.map +1 -0
  32. package/dist/better-auth/adapter/test/adapter.test.d.ts +1 -0
  33. package/dist/better-auth/adapter/test/adapter.test.js +181 -0
  34. package/dist/better-auth/adapter/test/adapter.test.js.map +1 -0
  35. package/dist/better-auth/adapter/test/better-auth-adapter-test.d.ts +7 -0
  36. package/dist/better-auth/adapter/test/better-auth-adapter-test.js +425 -0
  37. package/dist/better-auth/adapter/test/better-auth-adapter-test.js.map +1 -0
  38. package/dist/better-auth/adapter/test/schema.test.d.ts +1 -0
  39. package/dist/better-auth/adapter/test/schema.test.js +796 -0
  40. package/dist/better-auth/adapter/test/schema.test.js.map +1 -0
  41. package/dist/better-auth/adapter/test/test_payload1/schema.d.ts +23 -0
  42. package/dist/better-auth/adapter/test/test_payload1/schema.js +177 -0
  43. package/dist/better-auth/adapter/test/test_payload1/schema.js.map +1 -0
  44. package/dist/better-auth/adapter/test/test_payload2/schema.d.ts +23 -0
  45. package/dist/better-auth/adapter/test/test_payload2/schema.js +167 -0
  46. package/dist/better-auth/adapter/test/test_payload2/schema.js.map +1 -0
  47. package/dist/better-auth/adapter/test/test_payload3/schema.d.ts +23 -0
  48. package/dist/better-auth/adapter/test/test_payload3/schema.js +198 -0
  49. package/dist/better-auth/adapter/test/test_payload3/schema.js.map +1 -0
  50. package/dist/better-auth/adapter/transform/index.d.ts +16 -0
  51. package/dist/better-auth/adapter/transform/index.js +252 -0
  52. package/dist/better-auth/adapter/transform/index.js.map +1 -0
  53. package/dist/better-auth/adapter/types.d.ts +6 -0
  54. package/dist/better-auth/adapter/types.js +3 -0
  55. package/dist/better-auth/adapter/types.js.map +1 -0
  56. package/dist/better-auth/index.d.ts +6 -0
  57. package/dist/better-auth/index.js +8 -0
  58. package/dist/better-auth/index.js.map +1 -0
  59. package/dist/better-auth/plugin/collections/accounts/hooks/sync-password-to-user.d.ts +7 -0
  60. package/dist/better-auth/plugin/collections/accounts/hooks/sync-password-to-user.js +47 -0
  61. package/dist/better-auth/plugin/collections/accounts/hooks/sync-password-to-user.js.map +1 -0
  62. package/dist/better-auth/plugin/collections/users/endpoints/refresh-token.d.ts +6 -0
  63. package/dist/better-auth/plugin/collections/users/endpoints/refresh-token.js +106 -0
  64. package/dist/better-auth/plugin/collections/users/endpoints/refresh-token.js.map +1 -0
  65. package/dist/better-auth/plugin/collections/users/hooks/after-login.d.ts +11 -0
  66. package/dist/better-auth/plugin/collections/users/hooks/after-login.js +71 -0
  67. package/dist/better-auth/plugin/collections/users/hooks/after-login.js.map +1 -0
  68. package/dist/better-auth/plugin/collections/users/hooks/after-logout.d.ts +6 -0
  69. package/dist/better-auth/plugin/collections/users/hooks/after-logout.js +49 -0
  70. package/dist/better-auth/plugin/collections/users/hooks/after-logout.js.map +1 -0
  71. package/dist/better-auth/plugin/collections/users/hooks/before-login.d.ts +5 -0
  72. package/dist/better-auth/plugin/collections/users/hooks/before-login.js +18 -0
  73. package/dist/better-auth/plugin/collections/users/hooks/before-login.js.map +1 -0
  74. package/dist/better-auth/plugin/collections/users/hooks/clean-up-user-after-delete.d.ts +5 -0
  75. package/dist/better-auth/plugin/collections/users/hooks/clean-up-user-after-delete.js +33 -0
  76. package/dist/better-auth/plugin/collections/users/hooks/clean-up-user-after-delete.js.map +1 -0
  77. package/dist/better-auth/plugin/collections/users/hooks/on-verified-change.d.ts +2 -0
  78. package/dist/better-auth/plugin/collections/users/hooks/on-verified-change.js +14 -0
  79. package/dist/better-auth/plugin/collections/users/hooks/on-verified-change.js.map +1 -0
  80. package/dist/better-auth/plugin/collections/users/hooks/sync-account.d.ts +7 -0
  81. package/dist/better-auth/plugin/collections/users/hooks/sync-account.js +82 -0
  82. package/dist/better-auth/plugin/collections/users/hooks/sync-account.js.map +1 -0
  83. package/dist/better-auth/plugin/helpers/generate-verify-email-url.d.ts +29 -0
  84. package/dist/better-auth/plugin/helpers/generate-verify-email-url.js +46 -0
  85. package/dist/better-auth/plugin/helpers/generate-verify-email-url.js.map +1 -0
  86. package/dist/better-auth/plugin/helpers/get-ip.d.ts +2 -0
  87. package/dist/better-auth/plugin/helpers/get-ip.js +31 -0
  88. package/dist/better-auth/plugin/helpers/get-ip.js.map +1 -0
  89. package/dist/better-auth/plugin/helpers/index.d.ts +1 -0
  90. package/dist/better-auth/plugin/helpers/index.js +3 -0
  91. package/dist/better-auth/plugin/helpers/index.js.map +1 -0
  92. package/dist/better-auth/plugin/helpers/serialize-cookie.d.ts +104 -0
  93. package/dist/better-auth/plugin/helpers/serialize-cookie.js +186 -0
  94. package/dist/better-auth/plugin/helpers/serialize-cookie.js.map +1 -0
  95. package/dist/better-auth/plugin/index.d.ts +7 -0
  96. package/dist/better-auth/plugin/index.js +64 -0
  97. package/dist/better-auth/plugin/index.js.map +1 -0
  98. package/dist/better-auth/plugin/lib/auth-strategy.d.ts +8 -0
  99. package/dist/better-auth/plugin/lib/auth-strategy.js +48 -0
  100. package/dist/better-auth/plugin/lib/auth-strategy.js.map +1 -0
  101. package/dist/better-auth/plugin/lib/build-collection-configs.d.ts +11 -0
  102. package/dist/better-auth/plugin/lib/build-collection-configs.js +1558 -0
  103. package/dist/better-auth/plugin/lib/build-collection-configs.js.map +1 -0
  104. package/dist/better-auth/plugin/lib/config.d.ts +41 -0
  105. package/dist/better-auth/plugin/lib/config.js +43 -0
  106. package/dist/better-auth/plugin/lib/config.js.map +1 -0
  107. package/dist/better-auth/plugin/lib/ensure-password-set-before-create.d.ts +7 -0
  108. package/dist/better-auth/plugin/lib/ensure-password-set-before-create.js +24 -0
  109. package/dist/better-auth/plugin/lib/ensure-password-set-before-create.js.map +1 -0
  110. package/dist/better-auth/plugin/lib/get-payload-auth.d.ts +5 -0
  111. package/dist/better-auth/plugin/lib/get-payload-auth.js +9 -0
  112. package/dist/better-auth/plugin/lib/get-payload-auth.js.map +1 -0
  113. package/dist/better-auth/plugin/lib/get-required-collection-slugs.d.ts +9 -0
  114. package/dist/better-auth/plugin/lib/get-required-collection-slugs.js +52 -0
  115. package/dist/better-auth/plugin/lib/get-required-collection-slugs.js.map +1 -0
  116. package/dist/better-auth/plugin/lib/init-better-auth.d.ts +6 -0
  117. package/dist/better-auth/plugin/lib/init-better-auth.js +13 -0
  118. package/dist/better-auth/plugin/lib/init-better-auth.js.map +1 -0
  119. package/dist/better-auth/plugin/lib/password.d.ts +25 -0
  120. package/dist/better-auth/plugin/lib/password.js +63 -0
  121. package/dist/better-auth/plugin/lib/password.js.map +1 -0
  122. package/dist/better-auth/plugin/lib/payload-access.d.ts +14 -0
  123. package/dist/better-auth/plugin/lib/payload-access.js +64 -0
  124. package/dist/better-auth/plugin/lib/payload-access.js.map +1 -0
  125. package/dist/better-auth/plugin/lib/prepare-session-data.d.ts +21 -0
  126. package/dist/better-auth/plugin/lib/prepare-session-data.js +42 -0
  127. package/dist/better-auth/plugin/lib/prepare-session-data.js.map +1 -0
  128. package/dist/better-auth/plugin/lib/respect-save-to-jwt-fields-middleware.d.ts +15 -0
  129. package/dist/better-auth/plugin/lib/respect-save-to-jwt-fields-middleware.js +30 -0
  130. package/dist/better-auth/plugin/lib/respect-save-to-jwt-fields-middleware.js.map +1 -0
  131. package/dist/better-auth/plugin/lib/sanitize-auth-options.d.ts +5 -0
  132. package/dist/better-auth/plugin/lib/sanitize-auth-options.js +298 -0
  133. package/dist/better-auth/plugin/lib/sanitize-auth-options.js.map +1 -0
  134. package/dist/better-auth/plugin/payload/components/admin-buttons.d.ts +5 -0
  135. package/dist/better-auth/plugin/payload/components/admin-buttons.js +222 -0
  136. package/dist/better-auth/plugin/payload/components/admin-buttons.js.map +1 -0
  137. package/dist/better-auth/plugin/payload/components/login-redirect.d.ts +1 -0
  138. package/dist/better-auth/plugin/payload/components/login-redirect.js +6 -0
  139. package/dist/better-auth/plugin/payload/components/login-redirect.js.map +1 -0
  140. package/dist/better-auth/plugin/payload/components/logo.d.ts +1 -0
  141. package/dist/better-auth/plugin/payload/components/logo.js +36 -0
  142. package/dist/better-auth/plugin/payload/components/logo.js.map +1 -0
  143. package/dist/better-auth/plugin/payload/components/logout.d.ts +1 -0
  144. package/dist/better-auth/plugin/payload/components/logout.js +61 -0
  145. package/dist/better-auth/plugin/payload/components/logout.js.map +1 -0
  146. package/dist/better-auth/plugin/payload/components/sign-in.d.ts +3 -0
  147. package/dist/better-auth/plugin/payload/components/sign-in.js +384 -0
  148. package/dist/better-auth/plugin/payload/components/sign-in.js.map +1 -0
  149. package/dist/better-auth/plugin/payload/components/sign-up.d.ts +6 -0
  150. package/dist/better-auth/plugin/payload/components/sign-up.js +502 -0
  151. package/dist/better-auth/plugin/payload/components/sign-up.js.map +1 -0
  152. package/dist/better-auth/plugin/payload/components/styles.css +73 -0
  153. package/dist/better-auth/plugin/payload/components/ui/button.d.ts +10 -0
  154. package/dist/better-auth/plugin/payload/components/ui/button.js +42 -0
  155. package/dist/better-auth/plugin/payload/components/ui/button.js.map +1 -0
  156. package/dist/better-auth/plugin/payload/components/ui/card.d.ts +9 -0
  157. package/dist/better-auth/plugin/payload/components/ui/card.js +55 -0
  158. package/dist/better-auth/plugin/payload/components/ui/card.js.map +1 -0
  159. package/dist/better-auth/plugin/payload/components/ui/checkbox.d.ts +4 -0
  160. package/dist/better-auth/plugin/payload/components/ui/checkbox.js +23 -0
  161. package/dist/better-auth/plugin/payload/components/ui/checkbox.js.map +1 -0
  162. package/dist/better-auth/plugin/payload/components/ui/cn.d.ts +2 -0
  163. package/dist/better-auth/plugin/payload/components/ui/cn.js +7 -0
  164. package/dist/better-auth/plugin/payload/components/ui/cn.js.map +1 -0
  165. package/dist/better-auth/plugin/payload/components/ui/input.d.ts +3 -0
  166. package/dist/better-auth/plugin/payload/components/ui/input.js +14 -0
  167. package/dist/better-auth/plugin/payload/components/ui/input.js.map +1 -0
  168. package/dist/better-auth/plugin/payload/components/ui/label.d.ts +4 -0
  169. package/dist/better-auth/plugin/payload/components/ui/label.js +15 -0
  170. package/dist/better-auth/plugin/payload/components/ui/label.js.map +1 -0
  171. package/dist/better-auth/plugin/payload/components/ui/password-input.d.ts +2 -0
  172. package/dist/better-auth/plugin/payload/components/ui/password-input.js +55 -0
  173. package/dist/better-auth/plugin/payload/components/ui/password-input.js.map +1 -0
  174. package/dist/better-auth/plugin/payload/exports/client.d.ts +3 -0
  175. package/dist/better-auth/plugin/payload/exports/client.js +5 -0
  176. package/dist/better-auth/plugin/payload/exports/client.js.map +1 -0
  177. package/dist/better-auth/plugin/payload/exports/rsc.d.ts +5 -0
  178. package/dist/better-auth/plugin/payload/exports/rsc.js +7 -0
  179. package/dist/better-auth/plugin/payload/exports/rsc.js.map +1 -0
  180. package/dist/better-auth/plugin/payload/views/create-first-admin/index.d.ts +4 -0
  181. package/dist/better-auth/plugin/payload/views/create-first-admin/index.js +112 -0
  182. package/dist/better-auth/plugin/payload/views/create-first-admin/index.js.map +1 -0
  183. package/dist/better-auth/plugin/payload/views/login/index.d.ts +4 -0
  184. package/dist/better-auth/plugin/payload/views/login/index.js +78 -0
  185. package/dist/better-auth/plugin/payload/views/login/index.js.map +1 -0
  186. package/dist/better-auth/plugin/types.d.ts +224 -0
  187. package/dist/better-auth/plugin/types.js +3 -0
  188. package/dist/better-auth/plugin/types.js.map +1 -0
  189. package/dist/better-auth/types.d.ts +2 -0
  190. package/dist/better-auth/types.js +4 -0
  191. package/dist/better-auth/types.js.map +1 -0
  192. package/dist/clerk/index.d.ts +1 -0
  193. package/dist/clerk/index.js +3 -0
  194. package/dist/clerk/index.js.map +1 -0
  195. package/dist/index.js +7 -0
  196. package/dist/index.js.map +1 -0
  197. package/dist/kinde/index.d.ts +1 -0
  198. package/dist/kinde/index.js +3 -0
  199. package/dist/kinde/index.js.map +1 -0
  200. package/package.json +87 -0
@@ -0,0 +1,1558 @@
1
+ import { baseCollectionSlugs, betterAuthPluginSlugs } from './config';
2
+ import { betterAuthStrategy } from './auth-strategy';
3
+ import { getAfterLogoutHook } from '../collections/users/hooks/after-logout';
4
+ import { getRefreshTokenEndpoint } from '../collections/users/endpoints/refresh-token';
5
+ import { isAdminOrCurrentUserUpdateWithAllowedFields, isAdminOrCurrentUserWithRoles, isAdminWithRoles } from './payload-access';
6
+ import { cleanUpUserAfterDelete } from '../collections/users/hooks/clean-up-user-after-delete';
7
+ import { getSyncPasswordToUserHook } from '../collections/accounts/hooks/sync-password-to-user';
8
+ import { getSyncAccountHook } from '../collections/users/hooks/sync-account';
9
+ import { onVerifiedChange } from '../collections/users/hooks/on-verified-change';
10
+ import { getAfterLoginHook } from '../collections/users/hooks/after-login';
11
+ import { getBeforeLoginHook } from '../collections/users/hooks/before-login';
12
+ /**
13
+ * Builds the required collections based on the BetterAuth options and plugins
14
+ */ export function buildCollectionConfigs({ incomingCollections, requiredCollectionSlugs, pluginOptions, sanitizedBAOptions }) {
15
+ const userSlug = pluginOptions.users?.slug ?? baseCollectionSlugs.users;
16
+ const accountSlug = pluginOptions.accounts?.slug ?? baseCollectionSlugs.accounts;
17
+ const sessionSlug = pluginOptions.sessions?.slug ?? baseCollectionSlugs.sessions;
18
+ const verificationSlug = pluginOptions.verifications?.slug ?? baseCollectionSlugs.verifications;
19
+ const baPlugins = sanitizedBAOptions.plugins ?? null;
20
+ const adminRoles = pluginOptions.users?.adminRoles ?? [
21
+ 'admin'
22
+ ];
23
+ const getTimestampFields = ({ saveUpdatedAtToJWT = true, saveCreatedAtToJWT = true } = {})=>{
24
+ return [
25
+ {
26
+ name: 'updatedAt',
27
+ type: 'date',
28
+ saveToJWT: saveUpdatedAtToJWT,
29
+ admin: {
30
+ disableBulkEdit: true,
31
+ hidden: true
32
+ },
33
+ index: true,
34
+ label: ({ t })=>t('general:updatedAt')
35
+ },
36
+ {
37
+ name: 'createdAt',
38
+ saveToJWT: saveCreatedAtToJWT,
39
+ admin: {
40
+ disableBulkEdit: true,
41
+ hidden: true
42
+ },
43
+ type: 'date',
44
+ index: true,
45
+ label: ({ t })=>t('general:createdAt')
46
+ }
47
+ ];
48
+ };
49
+ const enhancedCollections = [];
50
+ requiredCollectionSlugs.forEach((slug)=>{
51
+ switch(slug){
52
+ case baseCollectionSlugs.users:
53
+ const existingUserCollection = incomingCollections.find((collection)=>collection.slug === userSlug);
54
+ const allowedFields = pluginOptions.users?.allowedFields ?? [
55
+ 'name'
56
+ ];
57
+ let usersCollection = {
58
+ ...existingUserCollection,
59
+ slug: userSlug,
60
+ admin: {
61
+ defaultColumns: [
62
+ 'email'
63
+ ],
64
+ useAsTitle: 'email',
65
+ ...existingUserCollection?.admin,
66
+ hidden: pluginOptions.users?.hidden ?? false
67
+ },
68
+ access: {
69
+ admin: ({ req })=>adminRoles.includes(req.user?.role ?? 'user'),
70
+ read: isAdminOrCurrentUserWithRoles({
71
+ adminRoles,
72
+ idField: 'id'
73
+ }),
74
+ create: isAdminWithRoles({
75
+ adminRoles
76
+ }),
77
+ delete: isAdminOrCurrentUserWithRoles({
78
+ adminRoles,
79
+ idField: 'id'
80
+ }),
81
+ update: isAdminOrCurrentUserUpdateWithAllowedFields({
82
+ allowedFields,
83
+ adminRoles,
84
+ userSlug
85
+ }),
86
+ ...existingUserCollection?.access ?? {}
87
+ },
88
+ endpoints: [
89
+ ...existingUserCollection?.endpoints ? existingUserCollection.endpoints : [],
90
+ getRefreshTokenEndpoint({
91
+ userSlug
92
+ })
93
+ ],
94
+ hooks: {
95
+ beforeChange: [
96
+ ...existingUserCollection?.hooks?.beforeChange ?? [],
97
+ onVerifiedChange
98
+ ],
99
+ afterChange: [
100
+ ...existingUserCollection?.hooks?.afterChange ?? [],
101
+ getSyncAccountHook({
102
+ userSlug,
103
+ accountSlug
104
+ })
105
+ ],
106
+ beforeLogin: [
107
+ ...existingUserCollection?.hooks?.beforeLogin ?? [],
108
+ getBeforeLoginHook()
109
+ ],
110
+ afterLogin: [
111
+ ...existingUserCollection?.hooks?.afterLogin ?? [],
112
+ getAfterLoginHook({
113
+ sessionsCollectionSlug: sessionSlug,
114
+ usersCollectionSlug: userSlug
115
+ })
116
+ ],
117
+ afterLogout: [
118
+ ...existingUserCollection?.hooks?.afterLogout ?? [],
119
+ getAfterLogoutHook({
120
+ sessionsCollectionSlug: sessionSlug
121
+ })
122
+ ],
123
+ afterDelete: [
124
+ ...existingUserCollection?.hooks?.afterDelete ?? [],
125
+ (args)=>cleanUpUserAfterDelete(args)
126
+ ]
127
+ },
128
+ auth: {
129
+ ...existingUserCollection && typeof existingUserCollection.auth === 'object' ? existingUserCollection.auth : {},
130
+ //disableLocalStrategy: false,
131
+ strategies: [
132
+ betterAuthStrategy(adminRoles, userSlug)
133
+ ]
134
+ },
135
+ fields: [
136
+ ...existingUserCollection?.fields ?? [],
137
+ {
138
+ name: 'betterAuthAdminButtons',
139
+ type: 'ui',
140
+ admin: {
141
+ position: 'sidebar',
142
+ components: {
143
+ Field: {
144
+ path: '@payload-auth/better-auth-plugin/client#AdminButtons',
145
+ clientProps: ()=>{
146
+ return {
147
+ userSlug
148
+ };
149
+ }
150
+ }
151
+ },
152
+ condition: ()=>{
153
+ // Only show the impersonate button if the admin plugin is enabled
154
+ return (baPlugins && baPlugins.some((plugin)=>plugin.id === 'admin')) ?? false;
155
+ }
156
+ }
157
+ },
158
+ {
159
+ name: 'name',
160
+ type: 'text',
161
+ label: 'Name',
162
+ saveToJWT: true,
163
+ admin: {
164
+ description: 'Users chosen display name'
165
+ }
166
+ },
167
+ {
168
+ name: 'email',
169
+ type: 'text',
170
+ required: true,
171
+ unique: true,
172
+ index: true,
173
+ label: 'Email',
174
+ admin: {
175
+ description: 'The email of the user'
176
+ }
177
+ },
178
+ {
179
+ name: 'emailVerified',
180
+ type: 'checkbox',
181
+ required: true,
182
+ defaultValue: false,
183
+ saveToJWT: true,
184
+ label: 'Email Verified',
185
+ admin: {
186
+ description: 'Whether the email of the user has been verified'
187
+ }
188
+ },
189
+ {
190
+ name: 'image',
191
+ type: 'text',
192
+ label: 'Image',
193
+ saveToJWT: true,
194
+ admin: {
195
+ description: 'The image of the user'
196
+ }
197
+ },
198
+ {
199
+ name: 'role',
200
+ type: 'select',
201
+ required: true,
202
+ defaultValue: 'user',
203
+ saveToJWT: true,
204
+ options: [
205
+ ...(pluginOptions.users?.roles ?? [
206
+ {
207
+ label: 'Admin',
208
+ value: 'admin'
209
+ },
210
+ {
211
+ label: 'User',
212
+ value: 'user'
213
+ }
214
+ ]).map((role)=>{
215
+ if (typeof role === 'string') {
216
+ return {
217
+ label: role.charAt(0).toUpperCase() + role.slice(1),
218
+ value: role
219
+ };
220
+ }
221
+ return role;
222
+ })
223
+ ],
224
+ label: 'Role',
225
+ admin: {
226
+ description: 'The role of the user'
227
+ }
228
+ },
229
+ ...getTimestampFields({
230
+ saveUpdatedAtToJWT: false,
231
+ saveCreatedAtToJWT: false
232
+ })
233
+ ]
234
+ };
235
+ if (baPlugins) {
236
+ baPlugins.forEach((plugin)=>{
237
+ switch(plugin.id){
238
+ case 'two-factor':
239
+ usersCollection.fields.push({
240
+ name: 'twoFactorEnabled',
241
+ type: 'checkbox',
242
+ defaultValue: false,
243
+ label: 'Two Factor Enabled',
244
+ admin: {
245
+ description: 'Whether the user has two factor authentication enabled'
246
+ }
247
+ });
248
+ break;
249
+ case 'username':
250
+ usersCollection.fields.push({
251
+ name: 'username',
252
+ type: 'text',
253
+ unique: true,
254
+ required: false,
255
+ label: 'Username',
256
+ admin: {
257
+ description: 'The username of the user'
258
+ }
259
+ }, {
260
+ name: 'displayUsername',
261
+ type: 'text',
262
+ required: true,
263
+ label: 'Display Username',
264
+ admin: {
265
+ description: 'The display username of the user'
266
+ }
267
+ });
268
+ break;
269
+ case 'anonymous':
270
+ usersCollection.fields.push({
271
+ name: 'isAnonymous',
272
+ type: 'checkbox',
273
+ defaultValue: false,
274
+ label: 'Is Anonymous',
275
+ admin: {
276
+ description: 'Whether the user is anonymous.'
277
+ }
278
+ });
279
+ break;
280
+ case 'phone-number':
281
+ usersCollection.fields.push({
282
+ name: 'phoneNumber',
283
+ type: 'text',
284
+ label: 'Phone Number',
285
+ admin: {
286
+ description: 'The phone number of the user'
287
+ }
288
+ }, {
289
+ name: 'phoneNumberVerified',
290
+ type: 'checkbox',
291
+ defaultValue: false,
292
+ label: 'Phone Number Verified',
293
+ admin: {
294
+ description: 'Whether the phone number of the user has been verified'
295
+ }
296
+ });
297
+ break;
298
+ case 'admin':
299
+ usersCollection.fields.push({
300
+ name: 'banned',
301
+ type: 'checkbox',
302
+ defaultValue: false,
303
+ label: 'Banned',
304
+ admin: {
305
+ description: 'Whether the user is banned from the platform'
306
+ }
307
+ }, {
308
+ name: 'banReason',
309
+ type: 'text',
310
+ label: 'Ban Reason',
311
+ admin: {
312
+ description: 'The reason for the ban'
313
+ }
314
+ }, {
315
+ name: 'banExpires',
316
+ type: 'date',
317
+ label: 'Ban Expires',
318
+ admin: {
319
+ description: 'The date and time when the ban will expire'
320
+ }
321
+ });
322
+ break;
323
+ case 'harmony-email':
324
+ usersCollection.fields.push({
325
+ name: 'normalizedEmail',
326
+ type: 'text',
327
+ required: false,
328
+ unique: true,
329
+ admin: {
330
+ readOnly: true,
331
+ description: 'The normalized email of the user'
332
+ }
333
+ });
334
+ break;
335
+ default:
336
+ break;
337
+ }
338
+ });
339
+ }
340
+ if (pluginOptions.users?.collectionOverrides) {
341
+ usersCollection = pluginOptions.users.collectionOverrides({
342
+ collection: usersCollection
343
+ });
344
+ }
345
+ enhancedCollections.push(usersCollection);
346
+ break;
347
+ case baseCollectionSlugs.accounts:
348
+ const existingAccountCollection = incomingCollections.find((collection)=>collection.slug === accountSlug);
349
+ let accountCollection = {
350
+ slug: accountSlug,
351
+ admin: {
352
+ useAsTitle: 'accountId',
353
+ description: 'Accounts are used to store user accounts for authentication providers',
354
+ ...existingAccountCollection?.admin,
355
+ hidden: pluginOptions.accounts?.hidden
356
+ },
357
+ hooks: {
358
+ afterChange: [
359
+ ...existingAccountCollection?.hooks?.afterChange ?? [],
360
+ getSyncPasswordToUserHook({
361
+ userSlug,
362
+ accountSlug
363
+ })
364
+ ]
365
+ },
366
+ access: {
367
+ create: isAdminWithRoles({
368
+ adminRoles
369
+ }),
370
+ delete: isAdminWithRoles({
371
+ adminRoles
372
+ }),
373
+ read: isAdminOrCurrentUserWithRoles({
374
+ adminRoles,
375
+ idField: 'user'
376
+ }),
377
+ update: isAdminWithRoles({
378
+ adminRoles
379
+ }),
380
+ ...existingAccountCollection?.access ?? {}
381
+ },
382
+ fields: [
383
+ ...existingAccountCollection?.fields ?? [],
384
+ {
385
+ name: 'user',
386
+ type: 'relationship',
387
+ relationTo: userSlug,
388
+ required: true,
389
+ index: true,
390
+ label: 'User',
391
+ admin: {
392
+ readOnly: true,
393
+ description: 'The user that the account belongs to'
394
+ }
395
+ },
396
+ {
397
+ name: 'accountId',
398
+ type: 'text',
399
+ label: 'Account ID',
400
+ required: true,
401
+ index: true,
402
+ admin: {
403
+ readOnly: true,
404
+ description: 'The id of the account as provided by the SSO or equal to userId for credential accounts'
405
+ }
406
+ },
407
+ {
408
+ name: 'providerId',
409
+ type: 'text',
410
+ required: true,
411
+ label: 'Provider ID',
412
+ admin: {
413
+ readOnly: true,
414
+ description: 'The id of the provider as provided by the SSO'
415
+ }
416
+ },
417
+ {
418
+ name: 'accessToken',
419
+ type: 'text',
420
+ label: 'Access Token',
421
+ admin: {
422
+ readOnly: true,
423
+ description: 'The access token of the account. Returned by the provider'
424
+ }
425
+ },
426
+ {
427
+ name: 'refreshToken',
428
+ type: 'text',
429
+ label: 'Refresh Token',
430
+ admin: {
431
+ readOnly: true,
432
+ description: 'The refresh token of the account. Returned by the provider'
433
+ }
434
+ },
435
+ {
436
+ name: 'accessTokenExpiresAt',
437
+ type: 'date',
438
+ label: 'Access Token Expires At',
439
+ admin: {
440
+ readOnly: true,
441
+ description: 'The date and time when the access token will expire'
442
+ }
443
+ },
444
+ {
445
+ name: 'refreshTokenExpiresAt',
446
+ type: 'date',
447
+ label: 'Refresh Token Expires At',
448
+ admin: {
449
+ readOnly: true,
450
+ description: 'The date and time when the refresh token will expire'
451
+ }
452
+ },
453
+ {
454
+ name: 'scope',
455
+ type: 'text',
456
+ label: 'Scope',
457
+ admin: {
458
+ readOnly: true,
459
+ description: 'The scope of the account. Returned by the provider'
460
+ }
461
+ },
462
+ {
463
+ name: 'idToken',
464
+ type: 'text',
465
+ label: 'ID Token',
466
+ admin: {
467
+ readOnly: true,
468
+ description: 'The id token for the account. Returned by the provider'
469
+ }
470
+ },
471
+ {
472
+ name: 'password',
473
+ type: 'text',
474
+ label: 'Password',
475
+ admin: {
476
+ readOnly: true,
477
+ hidden: true,
478
+ description: 'The hashed password of the account. Mainly used for email and password authentication'
479
+ }
480
+ },
481
+ ...getTimestampFields()
482
+ ],
483
+ ...existingAccountCollection
484
+ };
485
+ if (pluginOptions.accounts?.collectionOverrides) {
486
+ accountCollection = pluginOptions.accounts.collectionOverrides({
487
+ collection: accountCollection
488
+ });
489
+ }
490
+ enhancedCollections.push(accountCollection);
491
+ break;
492
+ case baseCollectionSlugs.sessions:
493
+ const existingSessionCollection = incomingCollections.find((collection)=>collection.slug === sessionSlug);
494
+ let sessionCollection = {
495
+ slug: sessionSlug,
496
+ admin: {
497
+ ...existingSessionCollection?.admin,
498
+ hidden: pluginOptions.sessions?.hidden,
499
+ description: 'Sessions are active sessions for users. They are used to authenticate users with a session token'
500
+ },
501
+ fields: [
502
+ ...existingSessionCollection?.fields ?? [],
503
+ {
504
+ name: 'user',
505
+ type: 'relationship',
506
+ relationTo: userSlug,
507
+ required: true,
508
+ saveToJWT: true,
509
+ index: true,
510
+ admin: {
511
+ readOnly: true,
512
+ description: 'The user that the session belongs to'
513
+ }
514
+ },
515
+ {
516
+ name: 'token',
517
+ type: 'text',
518
+ required: true,
519
+ unique: true,
520
+ index: true,
521
+ saveToJWT: true,
522
+ label: 'Token',
523
+ admin: {
524
+ description: 'The unique session token',
525
+ readOnly: true
526
+ }
527
+ },
528
+ {
529
+ name: 'expiresAt',
530
+ type: 'date',
531
+ required: true,
532
+ label: 'Expires At',
533
+ saveToJWT: true,
534
+ admin: {
535
+ description: 'The date and time when the session will expire',
536
+ readOnly: true
537
+ }
538
+ },
539
+ {
540
+ name: 'ipAddress',
541
+ type: 'text',
542
+ label: 'IP Address',
543
+ saveToJWT: true,
544
+ admin: {
545
+ description: 'The IP address of the device',
546
+ readOnly: true
547
+ }
548
+ },
549
+ {
550
+ name: 'userAgent',
551
+ type: 'text',
552
+ label: 'User Agent',
553
+ saveToJWT: true,
554
+ admin: {
555
+ description: 'The user agent information of the device',
556
+ readOnly: true
557
+ }
558
+ },
559
+ ...getTimestampFields()
560
+ ],
561
+ ...existingSessionCollection
562
+ };
563
+ if (baPlugins) {
564
+ baPlugins.forEach((plugin)=>{
565
+ switch(plugin.id){
566
+ case 'admin':
567
+ sessionCollection.fields.push({
568
+ name: 'impersonatedBy',
569
+ type: 'relationship',
570
+ relationTo: userSlug,
571
+ required: false,
572
+ label: 'Impersonated By',
573
+ admin: {
574
+ readOnly: true,
575
+ description: 'The admin who is impersonating this session'
576
+ }
577
+ });
578
+ break;
579
+ case 'organization':
580
+ sessionCollection.fields.push({
581
+ name: 'activeOrganization',
582
+ type: 'relationship',
583
+ relationTo: betterAuthPluginSlugs.organizations,
584
+ label: 'Active Organization',
585
+ admin: {
586
+ readOnly: true,
587
+ description: 'The currently active organization for the session'
588
+ }
589
+ });
590
+ break;
591
+ default:
592
+ break;
593
+ }
594
+ });
595
+ }
596
+ if (pluginOptions.sessions?.collectionOverrides) {
597
+ sessionCollection = pluginOptions.sessions.collectionOverrides({
598
+ collection: sessionCollection
599
+ });
600
+ }
601
+ enhancedCollections.push(sessionCollection);
602
+ break;
603
+ case baseCollectionSlugs.verifications:
604
+ const existingVerificationCollection = incomingCollections.find((collection)=>collection.slug === verificationSlug);
605
+ const verificationCollection = {
606
+ slug: verificationSlug,
607
+ admin: {
608
+ ...existingVerificationCollection?.admin,
609
+ hidden: pluginOptions.verifications?.hidden,
610
+ useAsTitle: 'identifier',
611
+ description: 'Verifications are used to verify authentication requests'
612
+ },
613
+ fields: [
614
+ ...existingVerificationCollection?.fields ?? [],
615
+ {
616
+ name: 'identifier',
617
+ type: 'text',
618
+ required: true,
619
+ index: true,
620
+ label: 'Identifier',
621
+ admin: {
622
+ description: 'The identifier of the verification request',
623
+ readOnly: true
624
+ }
625
+ },
626
+ {
627
+ name: 'value',
628
+ type: 'text',
629
+ required: true,
630
+ label: 'Value',
631
+ admin: {
632
+ description: 'The value to be verified',
633
+ readOnly: true
634
+ }
635
+ },
636
+ {
637
+ name: 'expiresAt',
638
+ type: 'date',
639
+ required: true,
640
+ label: 'Expires At',
641
+ admin: {
642
+ description: 'The date and time when the verification request will expire',
643
+ readOnly: true
644
+ }
645
+ }
646
+ ],
647
+ timestamps: true,
648
+ ...existingVerificationCollection
649
+ };
650
+ enhancedCollections.push(verificationCollection);
651
+ break;
652
+ case betterAuthPluginSlugs.organizations:
653
+ const organizationCollection = {
654
+ slug: betterAuthPluginSlugs.organizations,
655
+ admin: {
656
+ hidden: pluginOptions.hidePluginCollections ?? false,
657
+ useAsTitle: 'name',
658
+ description: 'Organizations are groups of users that share access to certain resources.'
659
+ },
660
+ fields: [
661
+ {
662
+ name: 'name',
663
+ type: 'text',
664
+ required: true,
665
+ label: 'Name',
666
+ admin: {
667
+ description: 'The name of the organization.'
668
+ }
669
+ },
670
+ {
671
+ name: 'slug',
672
+ type: 'text',
673
+ unique: true,
674
+ index: true,
675
+ label: 'Slug',
676
+ admin: {
677
+ description: 'The slug of the organization.'
678
+ }
679
+ },
680
+ {
681
+ name: 'logo',
682
+ type: 'text',
683
+ label: 'Logo',
684
+ admin: {
685
+ description: 'The logo of the organization.'
686
+ }
687
+ },
688
+ {
689
+ name: 'metadata',
690
+ type: 'json',
691
+ label: 'Metadata',
692
+ admin: {
693
+ description: 'Additional metadata for the organization.'
694
+ }
695
+ }
696
+ ],
697
+ timestamps: true
698
+ };
699
+ enhancedCollections.push(organizationCollection);
700
+ break;
701
+ case betterAuthPluginSlugs.members:
702
+ const memberCollection = {
703
+ slug: betterAuthPluginSlugs.members,
704
+ admin: {
705
+ hidden: pluginOptions.hidePluginCollections ?? false,
706
+ useAsTitle: 'organization',
707
+ description: 'Members of an organization.'
708
+ },
709
+ fields: [
710
+ {
711
+ name: 'organization',
712
+ type: 'relationship',
713
+ relationTo: betterAuthPluginSlugs.organizations,
714
+ required: true,
715
+ index: true,
716
+ label: 'Organization',
717
+ admin: {
718
+ readOnly: true,
719
+ description: 'The organization that the member belongs to.'
720
+ }
721
+ },
722
+ {
723
+ name: 'user',
724
+ type: 'relationship',
725
+ relationTo: userSlug,
726
+ required: true,
727
+ index: true,
728
+ label: 'User',
729
+ admin: {
730
+ readOnly: true,
731
+ description: 'The user that is a member of the organization.'
732
+ }
733
+ },
734
+ {
735
+ name: 'team',
736
+ type: 'relationship',
737
+ relationTo: betterAuthPluginSlugs.teams,
738
+ required: false,
739
+ label: 'Team',
740
+ admin: {
741
+ description: 'The team that the member belongs to.'
742
+ }
743
+ },
744
+ {
745
+ name: 'role',
746
+ type: 'text',
747
+ required: true,
748
+ defaultValue: 'member',
749
+ label: 'Role',
750
+ admin: {
751
+ description: 'The role of the member in the organization.'
752
+ }
753
+ }
754
+ ],
755
+ timestamps: true
756
+ };
757
+ enhancedCollections.push(memberCollection);
758
+ break;
759
+ case betterAuthPluginSlugs.invitations:
760
+ const invitationCollection = {
761
+ slug: betterAuthPluginSlugs.invitations,
762
+ admin: {
763
+ hidden: pluginOptions.hidePluginCollections ?? false,
764
+ useAsTitle: 'email',
765
+ description: 'Invitations to join an organization'
766
+ },
767
+ fields: [
768
+ {
769
+ name: 'email',
770
+ type: 'text',
771
+ required: true,
772
+ index: true,
773
+ label: 'Email',
774
+ admin: {
775
+ description: 'The email of the user being invited.',
776
+ readOnly: true
777
+ }
778
+ },
779
+ {
780
+ name: 'inviter',
781
+ type: 'relationship',
782
+ relationTo: userSlug,
783
+ required: true,
784
+ label: 'Inviter',
785
+ admin: {
786
+ description: 'The user who invited the user.',
787
+ readOnly: true
788
+ }
789
+ },
790
+ {
791
+ name: 'organization',
792
+ type: 'relationship',
793
+ relationTo: betterAuthPluginSlugs.organizations,
794
+ required: true,
795
+ index: true,
796
+ label: 'Organization',
797
+ admin: {
798
+ description: 'The organization that the user is being invited to.',
799
+ readOnly: true
800
+ }
801
+ },
802
+ {
803
+ name: 'role',
804
+ type: 'text',
805
+ required: true,
806
+ label: 'Role',
807
+ admin: {
808
+ description: 'The role of the user being invited.',
809
+ readOnly: true
810
+ }
811
+ },
812
+ {
813
+ name: 'status',
814
+ type: 'text',
815
+ required: true,
816
+ defaultValue: 'pending',
817
+ label: 'Status',
818
+ admin: {
819
+ description: 'The status of the invitation.',
820
+ readOnly: true
821
+ }
822
+ },
823
+ {
824
+ name: 'expiresAt',
825
+ type: 'date',
826
+ required: true,
827
+ label: 'Expires At',
828
+ admin: {
829
+ description: 'The date and time when the invitation will expire.',
830
+ readOnly: true
831
+ }
832
+ }
833
+ ],
834
+ timestamps: true
835
+ };
836
+ enhancedCollections.push(invitationCollection);
837
+ break;
838
+ case betterAuthPluginSlugs.teams:
839
+ const teamCollection = {
840
+ slug: betterAuthPluginSlugs.teams,
841
+ admin: {
842
+ hidden: pluginOptions.hidePluginCollections ?? false,
843
+ useAsTitle: 'name',
844
+ description: 'Teams are groups of users that share access to certain resources.'
845
+ },
846
+ fields: [
847
+ {
848
+ name: 'name',
849
+ type: 'text',
850
+ required: true,
851
+ label: 'Name',
852
+ admin: {
853
+ description: 'The name of the team.'
854
+ }
855
+ },
856
+ {
857
+ name: 'organization',
858
+ type: 'relationship',
859
+ relationTo: betterAuthPluginSlugs.organizations,
860
+ required: true,
861
+ label: 'Organization',
862
+ admin: {
863
+ readOnly: true,
864
+ description: 'The organization that the team belongs to.'
865
+ }
866
+ }
867
+ ],
868
+ timestamps: true
869
+ };
870
+ enhancedCollections.push(teamCollection);
871
+ break;
872
+ case betterAuthPluginSlugs.jwks:
873
+ const jwksCollection = {
874
+ slug: betterAuthPluginSlugs.jwks,
875
+ admin: {
876
+ hidden: pluginOptions.hidePluginCollections ?? false,
877
+ useAsTitle: 'publicKey',
878
+ description: 'JWKS are used to verify the signature of the JWT token'
879
+ },
880
+ fields: [
881
+ {
882
+ name: 'publicKey',
883
+ type: 'text',
884
+ required: true,
885
+ index: true,
886
+ label: 'Public Key',
887
+ admin: {
888
+ description: 'The public part of the web key'
889
+ }
890
+ },
891
+ {
892
+ name: 'privateKey',
893
+ type: 'text',
894
+ required: true,
895
+ label: 'Private Key',
896
+ admin: {
897
+ description: 'The private part of the web key'
898
+ }
899
+ }
900
+ ],
901
+ timestamps: true
902
+ };
903
+ enhancedCollections.push(jwksCollection);
904
+ break;
905
+ case betterAuthPluginSlugs.apiKeys:
906
+ const apiKeyCollection = {
907
+ slug: betterAuthPluginSlugs.apiKeys,
908
+ admin: {
909
+ hidden: pluginOptions.hidePluginCollections ?? false,
910
+ useAsTitle: 'name',
911
+ description: 'API keys are used to authenticate requests to the API.'
912
+ },
913
+ fields: [
914
+ {
915
+ name: 'name',
916
+ type: 'text',
917
+ label: 'Name',
918
+ admin: {
919
+ readOnly: true,
920
+ description: 'The name of the API key.'
921
+ }
922
+ },
923
+ {
924
+ name: 'start',
925
+ type: 'text',
926
+ label: 'Starting Characters',
927
+ admin: {
928
+ readOnly: true,
929
+ description: 'The starting characters of the API key. Useful for showing the first few characters of the API key in the UI for the users to easily identify.'
930
+ }
931
+ },
932
+ {
933
+ name: 'prefix',
934
+ type: 'text',
935
+ label: 'Prefix',
936
+ admin: {
937
+ readOnly: true,
938
+ description: 'The API Key prefix. Stored as plain text.'
939
+ }
940
+ },
941
+ {
942
+ name: 'key',
943
+ type: 'text',
944
+ required: true,
945
+ label: 'API Key',
946
+ admin: {
947
+ readOnly: true,
948
+ description: 'The hashed API key itself.'
949
+ }
950
+ },
951
+ {
952
+ name: 'user',
953
+ type: 'relationship',
954
+ relationTo: userSlug,
955
+ required: true,
956
+ label: 'User',
957
+ admin: {
958
+ readOnly: true,
959
+ description: 'The user associated with the API key.'
960
+ }
961
+ },
962
+ {
963
+ name: 'refillInterval',
964
+ type: 'number',
965
+ label: 'Refill Interval',
966
+ admin: {
967
+ readOnly: true,
968
+ description: 'The interval to refill the key in milliseconds.'
969
+ }
970
+ },
971
+ {
972
+ name: 'refillAmount',
973
+ type: 'number',
974
+ label: 'Refill Amount',
975
+ admin: {
976
+ readOnly: true,
977
+ description: 'The amount to refill the remaining count of the key.'
978
+ }
979
+ },
980
+ {
981
+ name: 'lastRefillAt',
982
+ type: 'date',
983
+ label: 'Last Refill At',
984
+ admin: {
985
+ readOnly: true,
986
+ description: 'The date and time when the key was last refilled.'
987
+ }
988
+ },
989
+ {
990
+ name: 'enabled',
991
+ type: 'checkbox',
992
+ defaultValue: true,
993
+ label: 'Enabled',
994
+ admin: {
995
+ readOnly: true,
996
+ description: 'Whether the API key is enabled.'
997
+ }
998
+ },
999
+ {
1000
+ name: 'rateLimitEnabled',
1001
+ type: 'checkbox',
1002
+ defaultValue: true,
1003
+ label: 'Rate Limit Enabled',
1004
+ admin: {
1005
+ readOnly: true,
1006
+ description: 'Whether the API key has rate limiting enabled.'
1007
+ }
1008
+ },
1009
+ {
1010
+ name: 'rateLimitTimeWindow',
1011
+ type: 'number',
1012
+ label: 'Rate Limit Time Window',
1013
+ admin: {
1014
+ readOnly: true,
1015
+ description: 'The time window in milliseconds for the rate limit.'
1016
+ }
1017
+ },
1018
+ {
1019
+ name: 'rateLimitMax',
1020
+ type: 'number',
1021
+ label: 'The maximum number of requests allowed within the `rateLimitTimeWindow`.',
1022
+ admin: {
1023
+ readOnly: true,
1024
+ description: 'The maximum number of requests allowed within the rate limit time window.'
1025
+ }
1026
+ },
1027
+ {
1028
+ name: 'requstCount',
1029
+ type: 'number',
1030
+ label: 'Request Count',
1031
+ required: true,
1032
+ admin: {
1033
+ readOnly: true,
1034
+ description: 'The number of requests made within the rate limit time window.'
1035
+ }
1036
+ },
1037
+ {
1038
+ name: 'remaining',
1039
+ type: 'number',
1040
+ label: 'Remaining Requests',
1041
+ admin: {
1042
+ readOnly: true,
1043
+ description: 'The number of requests remaining.'
1044
+ }
1045
+ },
1046
+ {
1047
+ name: 'lastRequest',
1048
+ type: 'date',
1049
+ label: 'Last Request At',
1050
+ admin: {
1051
+ readOnly: true,
1052
+ description: 'The date and time of the last request made to the key.'
1053
+ }
1054
+ },
1055
+ {
1056
+ name: 'expiresAt',
1057
+ type: 'date',
1058
+ label: 'Expires At',
1059
+ admin: {
1060
+ readOnly: true,
1061
+ description: 'The date and time of when the API key will expire.'
1062
+ }
1063
+ },
1064
+ {
1065
+ name: 'permissions',
1066
+ type: 'text',
1067
+ label: 'Permissions',
1068
+ admin: {
1069
+ readOnly: true,
1070
+ description: 'The permissions for the API key.'
1071
+ }
1072
+ },
1073
+ {
1074
+ name: 'metadata',
1075
+ type: 'json',
1076
+ label: 'Metadata',
1077
+ admin: {
1078
+ readOnly: true,
1079
+ description: 'Any additional metadata you want to store with the key.'
1080
+ }
1081
+ }
1082
+ ],
1083
+ timestamps: true
1084
+ };
1085
+ enhancedCollections.push(apiKeyCollection);
1086
+ break;
1087
+ case betterAuthPluginSlugs.twoFactors:
1088
+ const twoFactorCollection = {
1089
+ slug: betterAuthPluginSlugs.twoFactors,
1090
+ admin: {
1091
+ hidden: pluginOptions.hidePluginCollections ?? false,
1092
+ useAsTitle: 'secret',
1093
+ description: 'Two factor authentication secrets'
1094
+ },
1095
+ fields: [
1096
+ {
1097
+ name: 'user',
1098
+ type: 'relationship',
1099
+ relationTo: userSlug,
1100
+ required: true,
1101
+ label: 'User',
1102
+ admin: {
1103
+ readOnly: true,
1104
+ description: 'The user that the two factor authentication secret belongs to'
1105
+ }
1106
+ },
1107
+ {
1108
+ name: 'secret',
1109
+ type: 'text',
1110
+ label: 'Secret',
1111
+ index: true,
1112
+ admin: {
1113
+ readOnly: true,
1114
+ description: 'The secret used to generate the TOTP code.'
1115
+ }
1116
+ },
1117
+ {
1118
+ name: 'backupCodes',
1119
+ type: 'text',
1120
+ required: true,
1121
+ label: 'Backup Codes',
1122
+ admin: {
1123
+ readOnly: true,
1124
+ description: 'The backup codes used to recover access to the account if the user loses access to their phone or email'
1125
+ }
1126
+ }
1127
+ ],
1128
+ timestamps: true
1129
+ };
1130
+ enhancedCollections.push(twoFactorCollection);
1131
+ break;
1132
+ case betterAuthPluginSlugs.oauthAccessTokens:
1133
+ const oauthAccessTokenCollection = {
1134
+ slug: betterAuthPluginSlugs.oauthAccessTokens,
1135
+ admin: {
1136
+ hidden: pluginOptions.hidePluginCollections ?? false,
1137
+ useAsTitle: 'accessToken',
1138
+ description: 'OAuth access tokens for custom OAuth clients'
1139
+ },
1140
+ fields: [
1141
+ {
1142
+ name: 'accessToken',
1143
+ type: 'text',
1144
+ required: true,
1145
+ index: true,
1146
+ label: 'Access Token',
1147
+ admin: {
1148
+ readOnly: true,
1149
+ description: 'Access token issued to the client'
1150
+ }
1151
+ },
1152
+ {
1153
+ name: 'refreshToken',
1154
+ type: 'text',
1155
+ required: true,
1156
+ label: 'Refresh Token',
1157
+ admin: {
1158
+ readOnly: true,
1159
+ description: 'Refresh token issued to the client'
1160
+ }
1161
+ },
1162
+ {
1163
+ name: 'accessTokenExpiresAt',
1164
+ type: 'date',
1165
+ required: true,
1166
+ label: 'Access Token Expires At',
1167
+ admin: {
1168
+ readOnly: true,
1169
+ description: 'Expiration date of the access token'
1170
+ }
1171
+ },
1172
+ {
1173
+ name: 'refreshTokenExpiresAt',
1174
+ type: 'date',
1175
+ required: true,
1176
+ label: 'Refresh Token Expires At',
1177
+ admin: {
1178
+ readOnly: true,
1179
+ description: 'Expiration date of the refresh token'
1180
+ }
1181
+ },
1182
+ {
1183
+ name: 'client',
1184
+ type: 'relationship',
1185
+ relationTo: betterAuthPluginSlugs.oauthApplications,
1186
+ required: true,
1187
+ label: 'Client',
1188
+ admin: {
1189
+ readOnly: true,
1190
+ description: 'OAuth application associated with the access token'
1191
+ }
1192
+ },
1193
+ {
1194
+ name: 'user',
1195
+ type: 'relationship',
1196
+ relationTo: userSlug,
1197
+ required: true,
1198
+ label: 'User',
1199
+ admin: {
1200
+ readOnly: true,
1201
+ description: 'User associated with the access token'
1202
+ }
1203
+ },
1204
+ {
1205
+ name: 'scopes',
1206
+ type: 'text',
1207
+ required: true,
1208
+ label: 'Scopes',
1209
+ admin: {
1210
+ description: 'Comma-separated list of scopes granted'
1211
+ }
1212
+ }
1213
+ ],
1214
+ timestamps: true
1215
+ };
1216
+ enhancedCollections.push(oauthAccessTokenCollection);
1217
+ break;
1218
+ case betterAuthPluginSlugs.oauthApplications:
1219
+ const oauthApplicationCollection = {
1220
+ slug: betterAuthPluginSlugs.oauthApplications,
1221
+ admin: {
1222
+ hidden: pluginOptions.hidePluginCollections ?? false,
1223
+ useAsTitle: 'name',
1224
+ description: 'OAuth applications are custom OAuth clients'
1225
+ },
1226
+ fields: [
1227
+ {
1228
+ name: 'clientId',
1229
+ type: 'text',
1230
+ unique: true,
1231
+ index: true,
1232
+ required: true,
1233
+ label: 'Client ID',
1234
+ admin: {
1235
+ readOnly: true,
1236
+ description: 'Unique identifier for each OAuth client'
1237
+ }
1238
+ },
1239
+ {
1240
+ name: 'clientSecret',
1241
+ type: 'text',
1242
+ required: true,
1243
+ label: 'Client Secret',
1244
+ admin: {
1245
+ readOnly: true,
1246
+ description: 'Secret key for the OAuth client'
1247
+ }
1248
+ },
1249
+ {
1250
+ name: 'name',
1251
+ type: 'text',
1252
+ required: true,
1253
+ index: true,
1254
+ label: 'Name',
1255
+ admin: {
1256
+ description: 'Name of the OAuth application'
1257
+ }
1258
+ },
1259
+ {
1260
+ name: 'redirectURLs',
1261
+ type: 'text',
1262
+ required: true,
1263
+ label: 'Redirect URLs',
1264
+ admin: {
1265
+ description: 'Comma-separated list of redirect URLs'
1266
+ }
1267
+ },
1268
+ {
1269
+ name: 'metadata',
1270
+ type: 'json',
1271
+ admin: {
1272
+ readOnly: true,
1273
+ description: 'Additional metadata for the OAuth application'
1274
+ }
1275
+ },
1276
+ {
1277
+ name: 'type',
1278
+ type: 'text',
1279
+ required: true,
1280
+ label: 'Type',
1281
+ admin: {
1282
+ readOnly: true,
1283
+ description: 'Type of OAuth client (e.g., web, mobile)'
1284
+ }
1285
+ },
1286
+ {
1287
+ name: 'disabled',
1288
+ type: 'checkbox',
1289
+ defaultValue: false,
1290
+ required: true,
1291
+ label: 'Disabled',
1292
+ admin: {
1293
+ description: 'Indicates if the client is disabled'
1294
+ }
1295
+ },
1296
+ {
1297
+ name: 'icon',
1298
+ type: 'text',
1299
+ label: 'Icon',
1300
+ admin: {
1301
+ description: 'Icon of the OAuth application'
1302
+ }
1303
+ },
1304
+ {
1305
+ name: 'user',
1306
+ type: 'relationship',
1307
+ relationTo: userSlug,
1308
+ required: false,
1309
+ label: 'User',
1310
+ admin: {
1311
+ readOnly: true,
1312
+ description: 'ID of the user who owns the client. (optional)'
1313
+ }
1314
+ }
1315
+ ],
1316
+ timestamps: true
1317
+ };
1318
+ enhancedCollections.push(oauthApplicationCollection);
1319
+ break;
1320
+ case betterAuthPluginSlugs.oauthConsents:
1321
+ const oauthConsentCollection = {
1322
+ slug: betterAuthPluginSlugs.oauthConsents,
1323
+ admin: {
1324
+ hidden: pluginOptions.hidePluginCollections ?? false,
1325
+ description: 'OAuth consents are used to store user consents for OAuth clients'
1326
+ },
1327
+ fields: [
1328
+ {
1329
+ name: 'client',
1330
+ type: 'relationship',
1331
+ relationTo: betterAuthPluginSlugs.oauthApplications,
1332
+ required: true,
1333
+ label: 'Client',
1334
+ admin: {
1335
+ readOnly: true,
1336
+ description: 'OAuth client associated with the consent'
1337
+ }
1338
+ },
1339
+ {
1340
+ name: 'user',
1341
+ type: 'relationship',
1342
+ relationTo: userSlug,
1343
+ required: true,
1344
+ label: 'User',
1345
+ admin: {
1346
+ readOnly: true,
1347
+ description: 'User associated with the consent'
1348
+ }
1349
+ },
1350
+ {
1351
+ name: 'scopes',
1352
+ type: 'text',
1353
+ required: true,
1354
+ label: 'Scopes',
1355
+ admin: {
1356
+ readOnly: true,
1357
+ description: 'Comma-separated list of scopes consented to'
1358
+ }
1359
+ },
1360
+ {
1361
+ name: 'consentGiven',
1362
+ type: 'checkbox',
1363
+ defaultValue: false,
1364
+ required: true,
1365
+ label: 'Consent Given',
1366
+ admin: {
1367
+ readOnly: true,
1368
+ description: ' Indicates if consent was given'
1369
+ }
1370
+ }
1371
+ ],
1372
+ timestamps: true
1373
+ };
1374
+ enhancedCollections.push(oauthConsentCollection);
1375
+ break;
1376
+ case betterAuthPluginSlugs.passkeys:
1377
+ const passkeyCollection = {
1378
+ slug: betterAuthPluginSlugs.passkeys,
1379
+ admin: {
1380
+ hidden: pluginOptions.hidePluginCollections ?? false,
1381
+ useAsTitle: 'name',
1382
+ description: 'Passkeys are used to authenticate users'
1383
+ },
1384
+ fields: [
1385
+ {
1386
+ name: 'name',
1387
+ type: 'text',
1388
+ label: 'Name',
1389
+ admin: {
1390
+ readOnly: true,
1391
+ description: 'The name of the passkey'
1392
+ }
1393
+ },
1394
+ {
1395
+ name: 'publicKey',
1396
+ type: 'text',
1397
+ required: true,
1398
+ index: true,
1399
+ label: 'Public Key',
1400
+ admin: {
1401
+ readOnly: true,
1402
+ description: 'The public key of the passkey'
1403
+ }
1404
+ },
1405
+ {
1406
+ name: 'user',
1407
+ type: 'relationship',
1408
+ relationTo: userSlug,
1409
+ required: true,
1410
+ index: true,
1411
+ label: 'User',
1412
+ admin: {
1413
+ readOnly: true,
1414
+ description: 'The user that the passkey belongs to'
1415
+ }
1416
+ },
1417
+ {
1418
+ name: 'credentialID',
1419
+ type: 'text',
1420
+ required: true,
1421
+ unique: true,
1422
+ label: 'Credential ID',
1423
+ admin: {
1424
+ readOnly: true,
1425
+ description: 'The unique identifier of the registered credential'
1426
+ }
1427
+ },
1428
+ {
1429
+ name: 'counter',
1430
+ type: 'number',
1431
+ required: true,
1432
+ label: 'Counter',
1433
+ admin: {
1434
+ readOnly: true,
1435
+ description: 'The counter of the passkey'
1436
+ }
1437
+ },
1438
+ {
1439
+ name: 'deviceType',
1440
+ type: 'text',
1441
+ required: true,
1442
+ label: 'Device Type',
1443
+ admin: {
1444
+ readOnly: true,
1445
+ description: 'The type of device used to register the passkey'
1446
+ }
1447
+ },
1448
+ {
1449
+ name: 'backedUp',
1450
+ type: 'checkbox',
1451
+ required: true,
1452
+ label: 'Backed Up',
1453
+ admin: {
1454
+ readOnly: true,
1455
+ description: 'Whether the passkey is backed up'
1456
+ }
1457
+ },
1458
+ {
1459
+ name: 'transports',
1460
+ type: 'text',
1461
+ required: true,
1462
+ label: 'Transports',
1463
+ admin: {
1464
+ readOnly: true,
1465
+ description: 'The transports used to register the passkey'
1466
+ }
1467
+ }
1468
+ ],
1469
+ timestamps: true
1470
+ };
1471
+ enhancedCollections.push(passkeyCollection);
1472
+ break;
1473
+ case betterAuthPluginSlugs.ssoProviders:
1474
+ const ssoProviderCollection = {
1475
+ slug: betterAuthPluginSlugs.ssoProviders,
1476
+ admin: {
1477
+ hidden: pluginOptions.hidePluginCollections ?? false,
1478
+ useAsTitle: 'issuer',
1479
+ description: 'SSO providers are used to authenticate users with an external provider'
1480
+ },
1481
+ fields: [
1482
+ {
1483
+ name: 'issuer',
1484
+ type: 'text',
1485
+ required: true,
1486
+ index: true,
1487
+ label: 'Issuer',
1488
+ admin: {
1489
+ description: 'The issuer of the SSO provider'
1490
+ }
1491
+ },
1492
+ {
1493
+ name: 'domain',
1494
+ type: 'text',
1495
+ required: true,
1496
+ label: 'Domain',
1497
+ admin: {
1498
+ description: 'The domain of the SSO provider'
1499
+ }
1500
+ },
1501
+ {
1502
+ name: 'oidcConfig',
1503
+ type: 'text',
1504
+ required: true,
1505
+ label: 'OIDC Config',
1506
+ admin: {
1507
+ description: 'The OIDC config of the SSO provider'
1508
+ }
1509
+ },
1510
+ {
1511
+ name: 'user',
1512
+ type: 'relationship',
1513
+ relationTo: userSlug,
1514
+ required: true,
1515
+ label: 'User',
1516
+ admin: {
1517
+ description: 'The user associated with the SSO provider'
1518
+ }
1519
+ },
1520
+ {
1521
+ name: 'providerId',
1522
+ type: 'text',
1523
+ required: true,
1524
+ label: 'Provider ID',
1525
+ admin: {
1526
+ readOnly: true,
1527
+ description: 'The provider id. Used to identify a provider and to generate a redirect url'
1528
+ }
1529
+ },
1530
+ {
1531
+ name: 'organizationId',
1532
+ type: 'text',
1533
+ required: true,
1534
+ label: 'Organization ID',
1535
+ admin: {
1536
+ readOnly: true,
1537
+ description: 'The organization Id. If provider is linked to an organization'
1538
+ }
1539
+ }
1540
+ ],
1541
+ timestamps: true
1542
+ };
1543
+ enhancedCollections.push(ssoProviderCollection);
1544
+ break;
1545
+ default:
1546
+ break;
1547
+ }
1548
+ });
1549
+ const restOfCollections = incomingCollections.filter((collection)=>{
1550
+ return !enhancedCollections.some((enhancedCollection)=>enhancedCollection.slug === collection.slug);
1551
+ });
1552
+ return [
1553
+ ...enhancedCollections,
1554
+ ...restOfCollections
1555
+ ];
1556
+ }
1557
+
1558
+ //# sourceMappingURL=build-collection-configs.js.map