stackkit 0.3.4 → 0.3.6

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 (203) hide show
  1. package/README.md +50 -42
  2. package/dist/cli/add.js +122 -56
  3. package/dist/cli/create.d.ts +2 -0
  4. package/dist/cli/create.js +271 -95
  5. package/dist/cli/doctor.js +1 -0
  6. package/dist/cli/list.d.ts +1 -1
  7. package/dist/cli/list.js +6 -4
  8. package/dist/index.js +234 -191
  9. package/dist/lib/constants.d.ts +4 -0
  10. package/dist/lib/constants.js +4 -0
  11. package/dist/lib/discovery/module-discovery.d.ts +4 -0
  12. package/dist/lib/discovery/module-discovery.js +56 -0
  13. package/dist/lib/generation/code-generator.d.ts +11 -2
  14. package/dist/lib/generation/code-generator.js +42 -3
  15. package/dist/lib/generation/generator-utils.js +3 -1
  16. package/dist/lib/pm/package-manager.js +16 -13
  17. package/dist/lib/ui/logger.js +3 -2
  18. package/dist/lib/utils/path-resolver.d.ts +2 -0
  19. package/dist/lib/utils/path-resolver.js +8 -0
  20. package/dist/meta.json +8312 -0
  21. package/modules/auth/better-auth/files/{shared → express}/config/env.ts +48 -52
  22. package/modules/auth/better-auth/files/express/middlewares/authorize.ts +20 -1
  23. package/modules/auth/better-auth/files/express/modules/auth.controller.ts +349 -0
  24. package/modules/auth/better-auth/files/express/modules/{auth/auth.route.ts → auth.route.ts} +12 -7
  25. package/modules/auth/better-auth/files/express/modules/auth.service.ts +664 -0
  26. package/modules/auth/better-auth/files/express/modules/{auth/auth.type.ts → auth.type.ts} +22 -9
  27. package/modules/auth/better-auth/files/{shared/mongoose/auth/constants.ts → express/mongo-modules/auth.constants.ts} +0 -1
  28. package/modules/auth/better-auth/files/{shared/mongoose/auth/helper.ts → express/mongo-modules/auth.helper.ts} +11 -1
  29. package/modules/auth/better-auth/files/express/types/express.d.ts +11 -0
  30. package/modules/auth/better-auth/files/nextjs/api-route.ts +74 -0
  31. package/modules/auth/better-auth/files/nextjs/dashboard/pages/(user)/page.tsx +6 -0
  32. package/modules/auth/better-auth/files/nextjs/dashboard/pages/admin/page.tsx +6 -0
  33. package/modules/auth/better-auth/files/nextjs/dashboard/pages/layout.tsx +48 -0
  34. package/modules/auth/better-auth/files/nextjs/dashboard/pages/my-profile/page.tsx +5 -0
  35. package/modules/auth/better-auth/files/nextjs/features/services/auth.service.ts +102 -0
  36. package/modules/auth/better-auth/files/nextjs/layout/layout.tsx +13 -0
  37. package/modules/auth/better-auth/files/nextjs/lib/axios/http.ts +158 -0
  38. package/modules/auth/better-auth/files/nextjs/lib/env.ts +35 -0
  39. package/modules/auth/better-auth/files/nextjs/lib/utils/auth.ts +75 -0
  40. package/modules/auth/better-auth/files/nextjs/lib/utils/cookie.ts +29 -0
  41. package/modules/auth/better-auth/files/nextjs/lib/utils/jwt.ts +28 -0
  42. package/modules/auth/better-auth/files/nextjs/lib/utils/token.ts +49 -0
  43. package/modules/auth/better-auth/files/nextjs/pages/forgot-password/page.tsx +5 -0
  44. package/modules/auth/better-auth/files/nextjs/pages/layout.tsx +11 -0
  45. package/modules/auth/better-auth/files/nextjs/pages/login/page.tsx +9 -0
  46. package/modules/auth/better-auth/files/nextjs/pages/register/page.tsx +5 -0
  47. package/modules/auth/better-auth/files/nextjs/pages/reset-password/page.tsx +10 -0
  48. package/modules/auth/better-auth/files/nextjs/pages/verify-email/page.tsx +10 -0
  49. package/modules/auth/better-auth/files/nextjs/proxy.ts +157 -22
  50. package/modules/auth/better-auth/files/nextjs/theme/providers/theme-provider.tsx +11 -0
  51. package/modules/auth/better-auth/files/nextjs/types/api.types.ts +18 -0
  52. package/modules/auth/better-auth/files/react/components/protected-route.tsx +39 -0
  53. package/modules/auth/better-auth/files/react/components/route-guards.tsx +13 -0
  54. package/modules/auth/better-auth/files/react/dashboard/admin/pages/overview.tsx +3 -0
  55. package/modules/auth/better-auth/files/react/dashboard/pages/overview.tsx +3 -0
  56. package/modules/auth/better-auth/files/react/features/pages/forgot-password.tsx +5 -0
  57. package/modules/auth/better-auth/files/react/features/pages/login.tsx +5 -0
  58. package/modules/auth/better-auth/files/react/features/pages/my-profile.tsx +5 -0
  59. package/modules/auth/better-auth/files/react/features/pages/oauth-callback.tsx +59 -0
  60. package/modules/auth/better-auth/files/react/features/pages/register.tsx +5 -0
  61. package/modules/auth/better-auth/files/react/features/pages/reset-password.tsx +10 -0
  62. package/modules/auth/better-auth/files/react/features/pages/verify-email.tsx +10 -0
  63. package/modules/auth/better-auth/files/react/layout/dashboard-layout.tsx +54 -0
  64. package/modules/auth/better-auth/files/react/lib/axios/http.ts +68 -0
  65. package/modules/auth/better-auth/files/react/lib/env.ts +25 -0
  66. package/modules/auth/better-auth/files/react/router.tsx +73 -0
  67. package/modules/auth/better-auth/files/react/theme/components/providers/theme-provider-context.ts +13 -0
  68. package/modules/auth/better-auth/files/react/theme/components/providers/theme-provider.tsx +51 -0
  69. package/modules/auth/better-auth/files/react/theme/hooks/use-theme.ts +8 -0
  70. package/modules/auth/better-auth/files/shared/features/components/change-password-dialog.tsx +113 -0
  71. package/modules/auth/better-auth/files/shared/features/components/forgot-password-form.tsx +84 -0
  72. package/modules/auth/better-auth/files/shared/features/components/login-form.tsx +134 -0
  73. package/modules/auth/better-auth/files/shared/features/components/my-profile.tsx +147 -0
  74. package/modules/auth/better-auth/files/shared/features/components/profile-form.tsx +205 -0
  75. package/modules/auth/better-auth/files/shared/features/components/register-form.tsx +100 -0
  76. package/modules/auth/better-auth/files/shared/features/components/reset-password-form.tsx +111 -0
  77. package/modules/auth/better-auth/files/shared/features/components/social-login-buttons.tsx +47 -0
  78. package/modules/auth/better-auth/files/shared/features/components/user-profile-menu.tsx +106 -0
  79. package/modules/auth/better-auth/files/shared/features/components/verify-email-form.tsx +110 -0
  80. package/modules/auth/better-auth/files/shared/features/queries/auth.mutations.tsx +312 -0
  81. package/modules/auth/better-auth/files/shared/features/queries/auth.querie.ts +19 -0
  82. package/modules/auth/better-auth/files/shared/features/services/auth.api.ts +81 -0
  83. package/modules/auth/better-auth/files/shared/features/types/auth.type.ts +47 -0
  84. package/modules/auth/better-auth/files/shared/features/validators/change-password.validator.ts +18 -0
  85. package/modules/auth/better-auth/files/shared/features/validators/forgot.validator.ts +7 -0
  86. package/modules/auth/better-auth/files/shared/features/validators/login.validator.ts +14 -0
  87. package/modules/auth/better-auth/files/shared/features/validators/profile.validator.ts +8 -0
  88. package/modules/auth/better-auth/files/shared/features/validators/register.validator.ts +9 -0
  89. package/modules/auth/better-auth/files/shared/features/validators/reset.validator.ts +9 -0
  90. package/modules/auth/better-auth/files/shared/features/validators/verify.validator.ts +8 -0
  91. package/modules/auth/better-auth/files/shared/lib/auth-client.ts +2 -1
  92. package/modules/auth/better-auth/files/shared/lib/auth.ts +10 -29
  93. package/modules/auth/better-auth/files/shared/lib/constant/dashboard.ts +90 -0
  94. package/modules/auth/better-auth/files/shared/prisma/enums.prisma +0 -1
  95. package/modules/auth/better-auth/files/shared/theme/mode-toggle.tsx +30 -0
  96. package/modules/auth/better-auth/files/shared/ui/shadcn/components/dashboard/dashboard-header.tsx +94 -0
  97. package/modules/auth/better-auth/files/shared/ui/shadcn/components/dashboard/dashboard-sidebar.tsx +255 -0
  98. package/modules/auth/better-auth/files/shared/ui/shadcn/components/footer.tsx +35 -0
  99. package/modules/auth/better-auth/files/shared/ui/shadcn/components/navbar.tsx +145 -0
  100. package/modules/auth/better-auth/files/shared/ui/shadcn/form-field/input-field.tsx +440 -0
  101. package/modules/auth/better-auth/files/shared/utils/email.ts +20 -18
  102. package/modules/auth/better-auth/generator.json +174 -53
  103. package/modules/auth/better-auth/module.json +2 -2
  104. package/modules/components/files/shared/hooks/use-file-upload.ts +412 -0
  105. package/modules/components/files/shared/lib/utils/url-helpers.ts +110 -0
  106. package/modules/components/files/shared/shadcn/dashboard/data-table-column-selector.tsx +52 -0
  107. package/modules/components/files/shared/shadcn/dashboard/data-table-footer.tsx +156 -0
  108. package/modules/components/files/shared/shadcn/dashboard/data-table.tsx +405 -0
  109. package/modules/components/files/shared/shadcn/global/form-field/input-field.tsx +440 -0
  110. package/modules/components/files/shared/shadcn/global/form-field/media-uploader-field.tsx +745 -0
  111. package/modules/components/files/shared/shadcn/global/form-field/multi-select-field.tsx +207 -0
  112. package/modules/components/files/shared/shadcn/global/form-field/select-field.tsx +247 -0
  113. package/modules/components/files/shared/shadcn/global/form-field/textarea-field.tsx +277 -0
  114. package/modules/components/files/shared/shadcn/global/form-field/tiptap-editor-field.tsx +35 -0
  115. package/modules/components/files/shared/shadcn/global/no-results.tsx +41 -0
  116. package/modules/components/files/shared/shadcn/tiptap-editor/editor-menu-bar.tsx +217 -0
  117. package/modules/components/files/shared/shadcn/tiptap-editor/tiptap-editor.tsx +104 -0
  118. package/modules/components/files/shared/url/load-more.tsx +93 -0
  119. package/modules/components/files/shared/url/search-bar.tsx +131 -0
  120. package/modules/components/files/shared/url/sort-select.tsx +118 -0
  121. package/modules/components/files/shared/url/url-tabs.tsx +77 -0
  122. package/modules/components/generator.json +109 -0
  123. package/modules/components/module.json +11 -0
  124. package/modules/database/mongoose/generator.json +3 -14
  125. package/modules/database/mongoose/module.json +2 -2
  126. package/modules/database/prisma/generator.json +6 -12
  127. package/modules/database/prisma/module.json +2 -2
  128. package/modules/storage/cloudinary/files/express/config/env.ts +65 -0
  129. package/modules/storage/cloudinary/files/express/config/media.ts +103 -0
  130. package/modules/storage/cloudinary/files/express/modules/media/media.controller.ts +59 -0
  131. package/modules/storage/cloudinary/files/express/modules/media/media.route.ts +29 -0
  132. package/modules/storage/cloudinary/files/express/modules/media/media.service.ts +113 -0
  133. package/modules/storage/cloudinary/files/express/modules/media/media.type.ts +32 -0
  134. package/modules/storage/cloudinary/generator.json +34 -0
  135. package/modules/storage/cloudinary/module.json +11 -0
  136. package/modules/ui/shadcn/generator.json +21 -0
  137. package/modules/ui/shadcn/module.json +11 -0
  138. package/package.json +24 -26
  139. package/templates/express/README.md +11 -16
  140. package/templates/express/src/config/env.ts +7 -5
  141. package/templates/nextjs/README.md +13 -18
  142. package/templates/nextjs/app/favicon.ico +0 -0
  143. package/templates/nextjs/app/layout.tsx +6 -4
  144. package/templates/nextjs/components/providers/query-provider.tsx +3 -0
  145. package/templates/nextjs/env.example +3 -1
  146. package/templates/nextjs/lib/axios/http.ts +23 -0
  147. package/templates/nextjs/lib/env.ts +7 -5
  148. package/templates/nextjs/package.json +2 -1
  149. package/templates/nextjs/template.json +1 -2
  150. package/templates/react/README.md +9 -14
  151. package/templates/react/index.html +1 -1
  152. package/templates/react/package.json +1 -1
  153. package/templates/react/src/assets/favicon.ico +0 -0
  154. package/templates/react/src/components/providers/query-provider.tsx +38 -0
  155. package/templates/react/src/{shared/components → components}/seo.tsx +4 -8
  156. package/templates/react/src/lib/axios/http.ts +24 -0
  157. package/templates/react/src/main.tsx +8 -11
  158. package/templates/react/src/{features/about/pages → pages}/about.tsx +1 -1
  159. package/templates/react/src/{features/home/pages → pages}/home.tsx +1 -1
  160. package/templates/react/src/router.tsx +6 -6
  161. package/templates/react/src/vite-env.d.ts +2 -1
  162. package/templates/react/template.json +0 -1
  163. package/templates/react/tsconfig.app.json +6 -0
  164. package/templates/react/tsconfig.json +7 -1
  165. package/templates/react/vite.config.ts +12 -0
  166. package/modules/auth/authjs/files/nextjs/api/auth/[...nextauth]/route.ts +0 -3
  167. package/modules/auth/authjs/files/nextjs/proxy.ts +0 -1
  168. package/modules/auth/authjs/files/shared/lib/auth.ts +0 -119
  169. package/modules/auth/authjs/files/shared/prisma/schema.prisma +0 -61
  170. package/modules/auth/authjs/generator.json +0 -64
  171. package/modules/auth/authjs/module.json +0 -13
  172. package/modules/auth/better-auth/files/express/modules/auth/auth.controller.ts +0 -264
  173. package/modules/auth/better-auth/files/express/modules/auth/auth.service.ts +0 -537
  174. package/modules/auth/better-auth/files/express/templates/google-redirect.ejs +0 -24
  175. package/modules/auth/better-auth/files/nextjs/api/auth/[...all]/route.ts +0 -4
  176. package/modules/auth/better-auth/files/nextjs/lib/auth/auth-guards.ts +0 -41
  177. package/modules/auth/better-auth/files/nextjs/templates/email-otp.tsx +0 -74
  178. package/templates/express/node_modules/.bin/acorn +0 -17
  179. package/templates/express/node_modules/.bin/eslint +0 -17
  180. package/templates/express/node_modules/.bin/tsc +0 -17
  181. package/templates/express/node_modules/.bin/tsserver +0 -17
  182. package/templates/express/node_modules/.bin/tsx +0 -17
  183. package/templates/nextjs/lib/api/http.ts +0 -40
  184. package/templates/nextjs/next-env.d.ts +0 -6
  185. package/templates/react/dist/assets/index-D4AHT4dU.js +0 -193
  186. package/templates/react/dist/assets/index-rpwj5ZOX.css +0 -1
  187. package/templates/react/dist/index.html +0 -14
  188. package/templates/react/dist/vite.svg +0 -1
  189. package/templates/react/public/vite.svg +0 -1
  190. package/templates/react/src/app/layouts/dashboard-layout.tsx +0 -8
  191. package/templates/react/src/app/layouts/public-layout.tsx +0 -5
  192. package/templates/react/src/app/providers.tsx +0 -20
  193. package/templates/react/src/app/router.tsx +0 -21
  194. package/templates/react/src/assets/react.svg +0 -1
  195. package/templates/react/src/shared/api/http.ts +0 -39
  196. package/templates/react/src/shared/components/loading.tsx +0 -8
  197. package/templates/react/src/shared/lib/query-client.ts +0 -12
  198. package/templates/react/src/utils/storage.ts +0 -35
  199. package/templates/react/src/utils/utils.ts +0 -3
  200. /package/templates/nextjs/app/{page.tsx → (public)/(root)/page.tsx} +0 -0
  201. /package/templates/react/src/{shared/components → components}/error-boundary.tsx +0 -0
  202. /package/templates/react/src/{shared/components → components}/layout.tsx +0 -0
  203. /package/templates/react/src/{shared/pages → pages}/not-found.tsx +0 -0
@@ -1,537 +0,0 @@
1
- import status from "http-status";
2
- import { JwtPayload } from "jsonwebtoken";
3
- import { envVars } from "../../config/env";
4
- {{#if database == "prisma"}}
5
- import { prisma } from "../../database/prisma";
6
- {{/if}}
7
- {{#if database == "mongoose"}}
8
- import {
9
- deleteAuthUserById,
10
- getAuthCollections,
11
- } from "./auth.helper";
12
- {{/if}}
13
- import { auth } from "../../lib/auth";
14
- import { AppError } from "../../shared/errors/app-error";
15
- import { jwtUtils } from "../../shared/utils/jwt";
16
- import { tokenUtils } from "../../shared/utils/token";
17
- import {
18
- IChangePasswordPayload,
19
- ILoginUserPayload,
20
- IRegisterUserPayload,
21
- IRequestUser,
22
- } from "./auth.type";
23
-
24
- const registerUser = async (payload: IRegisterUserPayload) => {
25
- const { name, email, password } = payload;
26
-
27
- const data = await auth.api.signUpEmail({
28
- body: {
29
- name,
30
- email,
31
- password,
32
- },
33
- });
34
-
35
- if (!data.user) {
36
- throw new AppError(status.BAD_REQUEST, "Failed to register user");
37
- }
38
-
39
- try {
40
- const accessToken = tokenUtils.getAccessToken({
41
- userId: data.user.id,
42
- role: data.user.role,
43
- name: data.user.name,
44
- email: data.user.email,
45
- status: data.user.status,
46
- isDeleted: data.user.isDeleted,
47
- emailVerified: data.user.emailVerified,
48
- });
49
-
50
- const refreshToken = tokenUtils.getRefreshToken({
51
- userId: data.user.id,
52
- role: data.user.role,
53
- name: data.user.name,
54
- email: data.user.email,
55
- status: data.user.status,
56
- isDeleted: data.user.isDeleted,
57
- emailVerified: data.user.emailVerified,
58
- });
59
-
60
- return {
61
- ...data,
62
- accessToken,
63
- refreshToken,
64
- user: data.user,
65
- };
66
- } catch (error) {
67
- {{#if database == "prisma"}}
68
- await prisma.user.delete({
69
- where: {
70
- id: data.user.id,
71
- },
72
- });
73
- {{/if}}
74
- {{#if database == "mongoose"}}
75
- await deleteAuthUserById(data.user.id);
76
- {{/if}}
77
- throw error;
78
- }
79
-
80
- }
81
-
82
- const loginUser = async (payload: ILoginUserPayload) => {
83
- const { email, password } = payload;
84
-
85
- const data = await auth.api.signInEmail({
86
- body: {
87
- email,
88
- password,
89
- }
90
- })
91
-
92
- if (data.user.status === "BLOCKED") {
93
- throw new AppError(status.FORBIDDEN, "User is blocked");
94
- }
95
-
96
- if (data.user.isDeleted || data.user.status === "DELETED") {
97
- throw new AppError(status.NOT_FOUND, "User is deleted");
98
- }
99
-
100
- const accessToken = tokenUtils.getAccessToken({
101
- userId: data.user.id,
102
- role: data.user.role,
103
- name: data.user.name,
104
- email: data.user.email,
105
- status: data.user.status,
106
- isDeleted: data.user.isDeleted,
107
- emailVerified: data.user.emailVerified,
108
- });
109
-
110
- const refreshToken = tokenUtils.getRefreshToken({
111
- userId: data.user.id,
112
- role: data.user.role,
113
- name: data.user.name,
114
- email: data.user.email,
115
- status: data.user.status,
116
- isDeleted: data.user.isDeleted,
117
- emailVerified: data.user.emailVerified,
118
- });
119
-
120
- return {
121
- ...data,
122
- accessToken,
123
- refreshToken,
124
- };
125
- }
126
-
127
- const getMe = async (user : IRequestUser) => {
128
- {{#if database == "prisma"}}
129
- const isUserExists = await prisma.user.findUnique({
130
- where: {
131
- id: user.id,
132
- },
133
- // Include other related models if needed
134
- });
135
- {{/if}}
136
- {{#if database == "mongoose"}}
137
- const { users } = await getAuthCollections();
138
- const isUserExists = await users.findOne({ id: user.id });
139
- {{/if}}
140
-
141
- if (!isUserExists) {
142
- throw new AppError(status.NOT_FOUND, "User not found");
143
- }
144
-
145
- return isUserExists;
146
- }
147
-
148
- const getNewToken = async (refreshToken : string, sessionToken : string) => {
149
- {{#if database == "prisma"}}
150
- const isSessionTokenExists = await prisma.session.findUnique({
151
- where : {
152
- token : sessionToken,
153
- },
154
- include : {
155
- user : true,
156
- }
157
- })
158
- {{/if}}
159
- {{#if database == "mongoose"}}
160
- const { sessions } = await getAuthCollections();
161
-
162
- const isSessionTokenExists = await sessions.findOne({
163
- token: sessionToken,
164
- });
165
- {{/if}}
166
-
167
- if(!isSessionTokenExists){
168
- throw new AppError(status.UNAUTHORIZED, "Invalid session token");
169
- }
170
-
171
- const verifiedRefreshToken = jwtUtils.verifyToken(refreshToken, envVars.REFRESH_TOKEN_SECRET)
172
-
173
- if(!verifiedRefreshToken.success && verifiedRefreshToken.error){
174
- throw new AppError(status.UNAUTHORIZED, "Invalid refresh token");
175
- }
176
-
177
- const data = verifiedRefreshToken.data as JwtPayload;
178
-
179
- const newAccessToken = tokenUtils.getAccessToken({
180
- userId: data.userId,
181
- role: data.role,
182
- name: data.name,
183
- email: data.email,
184
- status: data.status,
185
- isDeleted: data.isDeleted,
186
- emailVerified: data.emailVerified,
187
- });
188
-
189
- const newRefreshToken = tokenUtils.getRefreshToken({
190
- userId: data.userId,
191
- role: data.role,
192
- name: data.name,
193
- email: data.email,
194
- status: data.status,
195
- isDeleted: data.isDeleted,
196
- emailVerified: data.emailVerified,
197
- });
198
-
199
- {{#if database == "prisma"}}
200
- const { token } = await prisma.session.update({
201
- where : {
202
- token : sessionToken
203
- },
204
- data : {
205
- token : sessionToken,
206
- expiresAt: new Date(Date.now() + 60 * 60 * 60 * 24 * 1000),
207
- updatedAt: new Date(),
208
- }
209
- })
210
- {{/if}}
211
- {{#if database == "mongoose"}}
212
- const updatedSession = await sessions.findOneAndUpdate(
213
- { token: sessionToken },
214
- {
215
- $set: {
216
- token: sessionToken,
217
- expiresAt: new Date(Date.now() + 60 * 60 * 60 * 24 * 1000),
218
- updatedAt: new Date(),
219
- },
220
- },
221
- {
222
- returnDocument: "after",
223
- },
224
- );
225
-
226
- if (!updatedSession) {
227
- throw new AppError(status.UNAUTHORIZED, "Session not found");
228
- }
229
- const token = updatedSession.token;
230
- {{/if}}
231
-
232
- return {
233
- accessToken : newAccessToken,
234
- refreshToken : newRefreshToken,
235
- sessionToken : token,
236
- };
237
- }
238
-
239
- const changePassword = async (payload : IChangePasswordPayload, sessionToken : string) =>{
240
- const session = await auth.api.getSession({
241
- headers : new Headers({
242
- Authorization : `Bearer ${sessionToken}`
243
- })
244
- })
245
-
246
- if(!session){
247
- throw new AppError(status.UNAUTHORIZED, "Invalid session token");
248
- }
249
-
250
- const {currentPassword, newPassword} = payload;
251
-
252
- const result = await auth.api.changePassword({
253
- body :{
254
- currentPassword,
255
- newPassword,
256
- revokeOtherSessions: true,
257
- },
258
- headers : new Headers({
259
- Authorization : `Bearer ${sessionToken}`
260
- })
261
- })
262
-
263
- if(session.user.needPasswordChange){
264
- {{#if database == "prisma"}}
265
- await prisma.user.update({
266
- where: {
267
- id: session.user.id,
268
- },
269
- data: {
270
- needPasswordChange: false,
271
- }
272
- })
273
- {{/if}}
274
- {{#if database == "mongoose"}}
275
- const { users } = await getAuthCollections();
276
- await users.updateOne(
277
- {
278
- id: session.user.id,
279
- },
280
- {
281
- $set: {
282
- needPasswordChange: false,
283
- },
284
- },
285
- );
286
- {{/if}}
287
- }
288
-
289
- const accessToken = tokenUtils.getAccessToken({
290
- userId: session.user.id,
291
- role: session.user.role,
292
- name: session.user.name,
293
- email: session.user.email,
294
- status: session.user.status,
295
- isDeleted: session.user.isDeleted,
296
- emailVerified: session.user.emailVerified,
297
- });
298
-
299
- const refreshToken = tokenUtils.getRefreshToken({
300
- userId: session.user.id,
301
- role: session.user.role,
302
- name: session.user.name,
303
- email: session.user.email,
304
- status: session.user.status,
305
- isDeleted: session.user.isDeleted,
306
- emailVerified: session.user.emailVerified,
307
- });
308
-
309
-
310
- return {
311
- ...result,
312
- accessToken,
313
- refreshToken,
314
- }
315
- }
316
-
317
- const logoutUser = async (sessionToken : string) => {
318
- const result = await auth.api.signOut({
319
- headers : new Headers({
320
- Authorization : `Bearer ${sessionToken}`
321
- })
322
- })
323
-
324
- return result;
325
- }
326
-
327
- const verifyEmail = async (email : string, otp : string) => {
328
-
329
- const result = await auth.api.verifyEmailOTP({
330
- body:{
331
- email,
332
- otp,
333
- }
334
- })
335
-
336
- if(result.status && !result.user.emailVerified){
337
- {{#if database == "prisma"}}
338
- await prisma.user.update({
339
- where : {
340
- email,
341
- },
342
- data : {
343
- emailVerified: true,
344
- }
345
- })
346
- {{/if}}
347
- {{#if database == "mongoose"}}
348
- const { users } = await getAuthCollections();
349
- await users.updateOne(
350
- {
351
- email,
352
- },
353
- {
354
- $set: {
355
- emailVerified: true,
356
- },
357
- },
358
- );
359
- {{/if}}
360
- }
361
- }
362
-
363
- const forgetPassword = async (email : string) => {
364
- {{#if database == "prisma"}}
365
- const isUserExist = await prisma.user.findUnique({
366
- where : {
367
- email,
368
- }
369
- })
370
- {{/if}}
371
- {{#if database == "mongoose"}}
372
- const { users } = await getAuthCollections();
373
- const isUserExist = await users.findOne({
374
- email,
375
- });
376
- {{/if}}
377
-
378
- if(!isUserExist){
379
- throw new AppError(status.NOT_FOUND, "User not found");
380
- }
381
-
382
- if(!isUserExist.emailVerified){
383
- throw new AppError(status.BAD_REQUEST, "Email not verified");
384
- }
385
-
386
- if (isUserExist.isDeleted || isUserExist.status === "DELETED") {
387
- throw new AppError(status.NOT_FOUND, "User not found");
388
- }
389
-
390
- await auth.api.requestPasswordResetEmailOTP({
391
- body:{
392
- email,
393
- }
394
- })
395
- }
396
-
397
- const resetPassword = async (email : string, otp : string, newPassword : string) => {
398
- {{#if database == "prisma"}}
399
- const isUserExist = await prisma.user.findUnique({
400
- where : {
401
- email,
402
- }
403
- })
404
- {{/if}}
405
- {{#if database == "mongoose"}}
406
- const { users } = await getAuthCollections();
407
- const isUserExist = await users.findOne({
408
- email,
409
- });
410
- {{/if}}
411
-
412
- if (!isUserExist) {
413
- throw new AppError(status.NOT_FOUND, "User not found");
414
- }
415
-
416
- if (!isUserExist.emailVerified) {
417
- throw new AppError(status.BAD_REQUEST, "Email not verified");
418
- }
419
-
420
- if (isUserExist.isDeleted || isUserExist.status === "DELETED") {
421
- throw new AppError(status.NOT_FOUND, "User not found");
422
- }
423
-
424
- await auth.api.resetPasswordEmailOTP({
425
- body:{
426
- email,
427
- otp,
428
- password : newPassword,
429
- }
430
- })
431
-
432
- {{#if database == "prisma"}}
433
- if (isUserExist.needPasswordChange) {
434
- await prisma.user.update({
435
- where: {
436
- email,
437
- },
438
- data: {
439
- needPasswordChange: false,
440
- }
441
- })
442
- }
443
-
444
- await prisma.session.deleteMany({
445
- where:{
446
- userId : isUserExist.id,
447
- }
448
- })
449
- {{/if}}
450
- {{#if database == "mongoose"}}
451
- if (isUserExist.needPasswordChange) {
452
- await users.updateOne(
453
- {
454
- email,
455
- },
456
- {
457
- $set: {
458
- needPasswordChange: false,
459
- },
460
- },
461
- );
462
- }
463
- const { sessions } = await getAuthCollections();
464
- await sessions.deleteMany({
465
- userId: isUserExist.id,
466
- });
467
- {{/if}}
468
- }
469
-
470
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
471
- const googleLoginSuccess = async (session : Record<string, any>) =>{
472
- {{#if database == "prisma"}}
473
- const isUserExists = await prisma.user.findUnique({
474
- where: {
475
- id: session.user.id,
476
- },
477
- });
478
-
479
- if (!isUserExists) {
480
- await prisma.user.create({
481
- data: {
482
- id: session.user.id,
483
- name: session.user.name,
484
- email: session.user.email,
485
- },
486
- });
487
- }
488
- {{/if}}
489
- {{#if database == "mongoose"}}
490
- const { users } = await getAuthCollections();
491
- const isUserExists = await users.findOne({ id: session.user.id });
492
-
493
- if (!isUserExists) {
494
- await users.insertOne({
495
- id: session.user.id,
496
- name: session.user.name,
497
- email: session.user.email,
498
- role: "USER",
499
- status: "ACTIVE",
500
- needPasswordChange: false,
501
- emailVerified: true,
502
- isDeleted: false,
503
- deletedAt: null,
504
- });
505
- }
506
- {{/if}}
507
-
508
- const accessToken = tokenUtils.getAccessToken({
509
- userId: session.user.id,
510
- role: session.user.role,
511
- name: session.user.name,
512
- });
513
-
514
- const refreshToken = tokenUtils.getRefreshToken({
515
- userId: session.user.id,
516
- role: session.user.role,
517
- name: session.user.name,
518
- });
519
-
520
- return {
521
- accessToken,
522
- refreshToken,
523
- }
524
- }
525
-
526
- export const authService = {
527
- registerUser: registerUser,
528
- loginUser,
529
- getMe,
530
- getNewToken,
531
- changePassword,
532
- logoutUser,
533
- verifyEmail,
534
- forgetPassword,
535
- resetPassword,
536
- googleLoginSuccess,
537
- };
@@ -1,24 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
-
4
- <head>
5
- <meta charset="UTF-8" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>Continue Sign-in</title>
8
- </head>
9
-
10
- <body style="font-family: Arial, Helvetica, sans-serif; padding: 24px;">
11
- <p>Redirecting to <%= provider %> login...</p>
12
-
13
- <form id="social-login-form" method="POST" action="<%= signInEndpoint %>">
14
- <input type="hidden" name="provider" value="<%= provider %>" />
15
- <input type="hidden" name="callbackURL" value="<%= callbackURL %>" />
16
- <button type="submit">Continue</button>
17
- </form>
18
-
19
- <script>
20
- document.getElementById("social-login-form")?.submit();
21
- </script>
22
- </body>
23
-
24
- </html>
@@ -1,4 +0,0 @@
1
- import { auth } from "@/server/auth/auth";
2
- import { toNextJsHandler } from "better-auth/next-js";
3
-
4
- export const { GET, POST } = toNextJsHandler(auth);
@@ -1,41 +0,0 @@
1
- import { headers } from "next/headers";
2
- import { redirect } from "next/navigation";
3
- import { auth } from "./auth";
4
-
5
- export async function getSession() {
6
- const session = await auth.api.getSession({
7
- headers: await headers(),
8
- });
9
-
10
- return session;
11
- }
12
-
13
- export async function requireSuperAdmin() {
14
- const session = await getSession();
15
-
16
- if (!session || session.user.role !== "SUPER_ADMIN") {
17
- redirect("/login");
18
- }
19
-
20
- return session.user;
21
- }
22
-
23
- export async function requireAdmin() {
24
- const session = await getSession();
25
-
26
- if (!session || session.user.role !== "ADMIN") {
27
- redirect("/login");
28
- }
29
-
30
- return session.user;
31
- }
32
-
33
- export async function getUser() {
34
- const session = await getSession();
35
-
36
- if (!session) {
37
- redirect("/login");
38
- }
39
-
40
- return session.user;
41
- }
@@ -1,74 +0,0 @@
1
- interface OtpTemplateProps {
2
- name?: string | null;
3
- otp: string;
4
- }
5
-
6
- const escapeHtml = (value: string) =>
7
- value
8
- .replaceAll("&", "&amp;")
9
- .replaceAll("<", "&lt;")
10
- .replaceAll(">", "&gt;")
11
- .replaceAll('"', "&quot;")
12
- .replaceAll("'", "&#39;");
13
-
14
- const renderOtpTemplate = ({ name, otp }: OtpTemplateProps) => {
15
- const safeName = name ? escapeHtml(name) : null;
16
- const safeOtp = escapeHtml(otp);
17
-
18
- return `<html>
19
- <body
20
- style="margin:0;padding:24px;background-color:#f8fafc;font-family:Arial,sans-serif;color:#0f172a;"
21
- >
22
- <table
23
- role="presentation"
24
- width="100%"
25
- cellpadding="0"
26
- cellspacing="0"
27
- style="max-width:560px;margin:0 auto;background:#ffffff;"
28
- >
29
- <tbody>
30
- <tr>
31
- <td style="padding:28px 24px;">
32
- <h2 style="margin:0 0 12px;font-size:22px;">Verification Code</h2>
33
- <p style="margin:0 0 16px;font-size:15px;line-height:1.6;">
34
- ${safeName ? `Hi ${safeName},` : "Hi,"}
35
- </p>
36
- <p style="margin:0 0 16px;font-size:15px;line-height:1.6;">
37
- Use the OTP below to continue. This code will expire in 2 minutes.
38
- </p>
39
- <div
40
- style="display:inline-block;padding:12px 18px;border:1px solid #e2e8f0;border-radius:8px;letter-spacing:6px;font-size:22px;font-weight:700;background-color:#f1f5f9;"
41
- >
42
- ${safeOtp}
43
- </div>
44
- <p style="margin:20px 0 0;font-size:13px;color:#475569;">
45
- If you did not request this code, you can safely ignore this email.
46
- </p>
47
- </td>
48
- </tr>
49
- </tbody>
50
- </table>
51
- </body>
52
- </html>`;
53
- };
54
-
55
- export const renderEmailTemplate = (
56
- templateName: string,
57
- templateData: Record<string, unknown>,
58
- ) => {
59
- switch (templateName) {
60
- case "otp": {
61
- const name =
62
- typeof templateData.name === "string" ? templateData.name : null;
63
- const otp = typeof templateData.otp === "string" ? templateData.otp : "";
64
-
65
- if (!otp) {
66
- throw new Error("OTP value is required for otp template");
67
- }
68
-
69
- return `<!DOCTYPE html>${renderOtpTemplate({ name, otp })}`;
70
- }
71
- default:
72
- throw new Error(`Unknown email template: ${templateName}`);
73
- }
74
- };
@@ -1,17 +0,0 @@
1
- #!/bin/sh
2
- basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
-
4
- case `uname` in
5
- *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
6
- esac
7
-
8
- if [ -z "$NODE_PATH" ]; then
9
- export NODE_PATH="/home/tariqul/Projects/open-source/stackkit/node_modules/.pnpm/acorn@8.15.0/node_modules/acorn/bin/node_modules:/home/tariqul/Projects/open-source/stackkit/node_modules/.pnpm/acorn@8.15.0/node_modules/acorn/node_modules:/home/tariqul/Projects/open-source/stackkit/node_modules/.pnpm/acorn@8.15.0/node_modules:/home/tariqul/Projects/open-source/stackkit/node_modules/.pnpm/node_modules"
10
- else
11
- export NODE_PATH="/home/tariqul/Projects/open-source/stackkit/node_modules/.pnpm/acorn@8.15.0/node_modules/acorn/bin/node_modules:/home/tariqul/Projects/open-source/stackkit/node_modules/.pnpm/acorn@8.15.0/node_modules/acorn/node_modules:/home/tariqul/Projects/open-source/stackkit/node_modules/.pnpm/acorn@8.15.0/node_modules:/home/tariqul/Projects/open-source/stackkit/node_modules/.pnpm/node_modules:$NODE_PATH"
12
- fi
13
- if [ -x "$basedir/node" ]; then
14
- exec "$basedir/node" "$basedir/../../../../node_modules/.pnpm/acorn@8.15.0/node_modules/acorn/bin/acorn" "$@"
15
- else
16
- exec node "$basedir/../../../../node_modules/.pnpm/acorn@8.15.0/node_modules/acorn/bin/acorn" "$@"
17
- fi