@appconda/nextjs 1.0.86 → 1.0.87

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.
@@ -21,7 +21,7 @@ export const actionClient = createSafeActionClient({
21
21
  },
22
22
  });
23
23
  export const authenticatedActionClient = actionClient.use(async ({ next }) => {
24
- const session = await getServerSession(authOptions);
24
+ const session = await getServerSession(authOptions());
25
25
  if (!session?.user) {
26
26
  throw new AuthenticationError("Not authenticated");
27
27
  }
@@ -1 +1 @@
1
- export declare const auth: () => Promise<import("next-auth").Session>;
1
+ export declare const auth: () => Promise<unknown>;
@@ -1,5 +1,5 @@
1
1
  import { getServerSession } from "next-auth";
2
2
  import { authOptions } from "./authOptions";
3
3
  export const auth = async () => {
4
- return await getServerSession(authOptions);
4
+ return await getServerSession(authOptions());
5
5
  };
@@ -1,6 +1,5 @@
1
- import type { NextAuthOptions } from "next-auth";
2
1
  export declare function signIn({ userName, password }: {
3
2
  userName: string;
4
3
  password: string;
5
4
  }): Promise<import("../modules/account/types").Session>;
6
- export declare const authOptions: NextAuthOptions;
5
+ export declare const authOptions: () => any;
@@ -2,17 +2,17 @@ import CredentialsProvider from "next-auth/providers/credentials";
2
2
  import { cookies } from "next/headers";
3
3
  import { getAppcondaClient } from "../getAppcondaClient";
4
4
  import { Account } from "../modules/account/service";
5
- //import { getEnv } from "../lib/env";
5
+ import { getEnv } from "../lib/env";
6
6
  import { getSDKForCurrentUser } from "../getSDKForCurrentUser";
7
7
  import { Query } from "../query";
8
- const getEnv = () => {
9
- return {
10
- APPCONDA_ENDPOINT: 'process.env.APPCONDA_ENDPOINT',
11
- APPCONDA_CLIENT_ENDPOINT: 'process.env.APPCONDA_CLIENT_ENDPOINT',
12
- _SERVICE_TOKEN: 'process.env._SERVICE_TOKEN',
13
- ENTERPRISE_LICENSE_KEY: 'process.env.ENTERPRISE_LICENSE_KEY',
14
- };
15
- };
8
+ /* const getEnv = () => {
9
+ return {
10
+ APPCONDA_ENDPOINT: 'process.env.APPCONDA_ENDPOINT',
11
+ APPCONDA_CLIENT_ENDPOINT: 'process.env.APPCONDA_CLIENT_ENDPOINT',
12
+ _SERVICE_TOKEN: 'process.env._SERVICE_TOKEN',
13
+ ENTERPRISE_LICENSE_KEY: 'process.env.ENTERPRISE_LICENSE_KEY',
14
+ };
15
+ }; */
16
16
  export async function signIn({ userName, password }) {
17
17
  const adminClient = await getAppcondaClient();
18
18
  const account = new Account(adminClient);
@@ -26,200 +26,208 @@ export async function signIn({ userName, password }) {
26
26
  });
27
27
  return session;
28
28
  }
29
- export const authOptions = {
30
- providers: [
31
- CredentialsProvider({
32
- id: "credentials",
33
- // The name to display on the sign in form (e.g. "Sign in with...")
34
- name: "Credentials",
35
- // The credentials is used to generate a suitable form on the sign in page.
36
- // You can specify whatever fields you are expecting to be submitted.
37
- // e.g. domain, username, password, 2FA token, etc.
38
- // You can pass any HTML attribute to the <input> tag through the object.
39
- credentials: {
40
- email: {
41
- label: "Email Address",
42
- type: "email",
43
- placeholder: "Your email address",
44
- },
45
- password: {
46
- label: "Password",
47
- type: "password",
48
- placeholder: "Your password",
29
+ export const authOptions = (() => {
30
+ let options = null;
31
+ return () => {
32
+ if (options == null) {
33
+ options = {
34
+ providers: [
35
+ CredentialsProvider({
36
+ id: "credentials",
37
+ // The name to display on the sign in form (e.g. "Sign in with...")
38
+ name: "Credentials",
39
+ // The credentials is used to generate a suitable form on the sign in page.
40
+ // You can specify whatever fields you are expecting to be submitted.
41
+ // e.g. domain, username, password, 2FA token, etc.
42
+ // You can pass any HTML attribute to the <input> tag through the object.
43
+ credentials: {
44
+ email: {
45
+ label: "Email Address",
46
+ type: "email",
47
+ placeholder: "Your email address",
48
+ },
49
+ password: {
50
+ label: "Password",
51
+ type: "password",
52
+ placeholder: "Your password",
53
+ },
54
+ totpCode: { label: "Two-factor Code", type: "input", placeholder: "Code from authenticator app" },
55
+ backupCode: { label: "Backup Code", type: "input", placeholder: "Two-factor backup code" },
56
+ },
57
+ async authorize(credentials, _req) {
58
+ let user;
59
+ const appcondaSession = await signIn({ userName: credentials?.email, password: credentials?.password });
60
+ console.log(credentials);
61
+ /* try {
62
+ user = await prisma.user.findUnique({
63
+ where: {
64
+ email: credentials?.email,
65
+ },
66
+ });
67
+ } catch (e) {
68
+ console.error(e);
69
+ throw Error("Internal server error. Please try again later");
70
+ }
71
+ if (!user || !credentials) {
72
+ throw new Error("Invalid credentials");
73
+ }
74
+ if (!user.password) {
75
+ throw new Error("Invalid credentials");
76
+ }
77
+
78
+ const isValid = await verifyPassword(credentials.password, user.password);
79
+
80
+ if (!isValid) {
81
+ throw new Error("Invalid credentials");
82
+ }
83
+
84
+ if (user.twoFactorEnabled && credentials.backupCode) {
85
+ if (!ENCRYPTION_KEY) {
86
+ console.error("Missing encryption key; cannot proceed with backup code login.");
87
+ throw new Error("Internal Server Error");
88
+ }
89
+
90
+ if (!user.backupCodes) throw new Error("No backup codes found");
91
+
92
+ const backupCodes = JSON.parse(symmetricDecrypt(user.backupCodes, ENCRYPTION_KEY));
93
+
94
+ // check if user-supplied code matches one
95
+ const index = backupCodes.indexOf(credentials.backupCode.replaceAll("-", ""));
96
+ if (index === -1) throw new Error("Invalid backup code");
97
+
98
+ // delete verified backup code and re-encrypt remaining
99
+ backupCodes[index] = null;
100
+ await prisma.user.update({
101
+ where: {
102
+ id: user.id,
103
+ },
104
+ data: {
105
+ backupCodes: symmetricEncrypt(JSON.stringify(backupCodes), ENCRYPTION_KEY),
106
+ },
107
+ });
108
+ } else if (user.twoFactorEnabled) {
109
+ if (!credentials.totpCode) {
110
+ throw new Error("second factor required");
111
+ }
112
+
113
+ if (!user.twoFactorSecret) {
114
+ throw new Error("Internal Server Error");
115
+ }
116
+
117
+ if (!ENCRYPTION_KEY) {
118
+ throw new Error("Internal Server Error");
119
+ }
120
+
121
+ const secret = symmetricDecrypt(user.twoFactorSecret, ENCRYPTION_KEY);
122
+ if (secret.length !== 32) {
123
+ throw new Error("Internal Server Error");
124
+ }
125
+
126
+ const isValidToken = (await import("./totp")).totpAuthenticatorCheck(credentials.totpCode, secret);
127
+ if (!isValidToken) {
128
+ throw new Error("Invalid second factor code");
129
+ }
130
+ } */
131
+ console.log("asafdf");
132
+ return {
133
+ id: appcondaSession.userId,
134
+ email: appcondaSession.providerUid,
135
+ emailVerified: true,
136
+ imageUrl: "",
137
+ };
138
+ },
139
+ }),
140
+ CredentialsProvider({
141
+ id: "token",
142
+ // The name to display on the sign in form (e.g. "Sign in with...")
143
+ name: "Token",
144
+ // The credentials is used to generate a suitable form on the sign in page.
145
+ // You can specify whatever fields you are expecting to be submitted.
146
+ // e.g. domain, username, password, 2FA token, etc.
147
+ // You can pass any HTML attribute to the <input> tag through the object.
148
+ credentials: {
149
+ token: {
150
+ label: "Verification Token",
151
+ type: "string",
152
+ },
153
+ },
154
+ async authorize(credentials, _req) {
155
+ let user;
156
+ /* try {
157
+ if (!credentials?.token) {
158
+ throw new Error("Token not found");
159
+ }
160
+ const { id } = await verifyToken(credentials?.token);
161
+ user = await prisma.user.findUnique({
162
+ where: {
163
+ id: id,
164
+ },
165
+ });
166
+ } catch (e) {
167
+ console.error(e);
168
+ throw new Error("Either a user does not match the provided token or the token is invalid");
169
+ }
170
+
171
+ if (!user) {
172
+ throw new Error("Either a user does not match the provided token or the token is invalid");
173
+ }
174
+
175
+ if (user.emailVerified) {
176
+ throw new Error("Email already verified");
177
+ }
178
+
179
+ user = await updateUser(user.id, { emailVerified: new Date() }); */
180
+ return user || null;
181
+ },
182
+ }),
183
+ // Conditionally add enterprise SSO providers
184
+ ...(getEnv().ENTERPRISE_LICENSE_KEY ? [] : []),
185
+ ],
186
+ callbacks: {
187
+ async jwt({ token }) {
188
+ const { users } = await getSDKForCurrentUser();
189
+ const userList = await users.list([Query.equal("email", token.email)]);
190
+ const user = userList.users[0] ?? {};
191
+ /* const existingUser = await getUserByEmail(token?.email!);
192
+
193
+ if (!existingUser) {
194
+ return token;
195
+ } */
196
+ return {
197
+ ...token,
198
+ //@ts-ignore
199
+ profile: { id: user.$id, ...user },
200
+ };
201
+ },
202
+ async session({ session, token }) {
203
+ //@ts-ignore
204
+ session.user.id = token?.id;
205
+ //@ts-ignore
206
+ session.user = token.profile;
207
+ return session;
208
+ },
209
+ //@ts-ignore
210
+ async signIn({ user, account }) {
211
+ /* if (account?.provider === "credentials" || account?.provider === "token") {
212
+ // check if user's email is verified or not
213
+ if (!user.emailVerified && !EMAIL_VERIFICATION_DISABLED) {
214
+ throw new Error("Email Verification is Pending");
215
+ }
216
+ return true;
217
+ }
218
+ if (ENTERPRISE_LICENSE_KEY) {
219
+ return handleSSOCallback({ user, account });
220
+ } */
221
+ return true;
222
+ },
49
223
  },
50
- totpCode: { label: "Two-factor Code", type: "input", placeholder: "Code from authenticator app" },
51
- backupCode: { label: "Backup Code", type: "input", placeholder: "Two-factor backup code" },
52
- },
53
- async authorize(credentials, _req) {
54
- let user;
55
- const appcondaSession = await signIn({ userName: credentials?.email, password: credentials?.password });
56
- console.log(credentials);
57
- /* try {
58
- user = await prisma.user.findUnique({
59
- where: {
60
- email: credentials?.email,
61
- },
62
- });
63
- } catch (e) {
64
- console.error(e);
65
- throw Error("Internal server error. Please try again later");
66
- }
67
- if (!user || !credentials) {
68
- throw new Error("Invalid credentials");
69
- }
70
- if (!user.password) {
71
- throw new Error("Invalid credentials");
72
- }
73
-
74
- const isValid = await verifyPassword(credentials.password, user.password);
75
-
76
- if (!isValid) {
77
- throw new Error("Invalid credentials");
78
- }
79
-
80
- if (user.twoFactorEnabled && credentials.backupCode) {
81
- if (!ENCRYPTION_KEY) {
82
- console.error("Missing encryption key; cannot proceed with backup code login.");
83
- throw new Error("Internal Server Error");
84
- }
85
-
86
- if (!user.backupCodes) throw new Error("No backup codes found");
87
-
88
- const backupCodes = JSON.parse(symmetricDecrypt(user.backupCodes, ENCRYPTION_KEY));
89
-
90
- // check if user-supplied code matches one
91
- const index = backupCodes.indexOf(credentials.backupCode.replaceAll("-", ""));
92
- if (index === -1) throw new Error("Invalid backup code");
93
-
94
- // delete verified backup code and re-encrypt remaining
95
- backupCodes[index] = null;
96
- await prisma.user.update({
97
- where: {
98
- id: user.id,
99
- },
100
- data: {
101
- backupCodes: symmetricEncrypt(JSON.stringify(backupCodes), ENCRYPTION_KEY),
102
- },
103
- });
104
- } else if (user.twoFactorEnabled) {
105
- if (!credentials.totpCode) {
106
- throw new Error("second factor required");
107
- }
108
-
109
- if (!user.twoFactorSecret) {
110
- throw new Error("Internal Server Error");
111
- }
112
-
113
- if (!ENCRYPTION_KEY) {
114
- throw new Error("Internal Server Error");
115
- }
116
-
117
- const secret = symmetricDecrypt(user.twoFactorSecret, ENCRYPTION_KEY);
118
- if (secret.length !== 32) {
119
- throw new Error("Internal Server Error");
120
- }
121
-
122
- const isValidToken = (await import("./totp")).totpAuthenticatorCheck(credentials.totpCode, secret);
123
- if (!isValidToken) {
124
- throw new Error("Invalid second factor code");
125
- }
126
- } */
127
- console.log("asafdf");
128
- return {
129
- id: appcondaSession.userId,
130
- email: appcondaSession.providerUid,
131
- emailVerified: true,
132
- imageUrl: "",
133
- };
134
- },
135
- }),
136
- CredentialsProvider({
137
- id: "token",
138
- // The name to display on the sign in form (e.g. "Sign in with...")
139
- name: "Token",
140
- // The credentials is used to generate a suitable form on the sign in page.
141
- // You can specify whatever fields you are expecting to be submitted.
142
- // e.g. domain, username, password, 2FA token, etc.
143
- // You can pass any HTML attribute to the <input> tag through the object.
144
- credentials: {
145
- token: {
146
- label: "Verification Token",
147
- type: "string",
224
+ pages: {
225
+ signIn: "/auth/login",
226
+ signOut: "/auth/logout",
227
+ error: "/auth/login", // Error code passed in query string as ?error=
148
228
  },
149
- },
150
- async authorize(credentials, _req) {
151
- let user;
152
- /* try {
153
- if (!credentials?.token) {
154
- throw new Error("Token not found");
155
- }
156
- const { id } = await verifyToken(credentials?.token);
157
- user = await prisma.user.findUnique({
158
- where: {
159
- id: id,
160
- },
161
- });
162
- } catch (e) {
163
- console.error(e);
164
- throw new Error("Either a user does not match the provided token or the token is invalid");
165
- }
166
-
167
- if (!user) {
168
- throw new Error("Either a user does not match the provided token or the token is invalid");
169
- }
170
-
171
- if (user.emailVerified) {
172
- throw new Error("Email already verified");
173
- }
174
-
175
- user = await updateUser(user.id, { emailVerified: new Date() }); */
176
- return user || null;
177
- },
178
- }),
179
- // Conditionally add enterprise SSO providers
180
- ...(getEnv().ENTERPRISE_LICENSE_KEY ? [] : []),
181
- ],
182
- callbacks: {
183
- async jwt({ token }) {
184
- const { users } = await getSDKForCurrentUser();
185
- const userList = await users.list([Query.equal("email", token.email)]);
186
- const user = userList.users[0] ?? {};
187
- /* const existingUser = await getUserByEmail(token?.email!);
188
-
189
- if (!existingUser) {
190
- return token;
191
- } */
192
- return {
193
- ...token,
194
- //@ts-ignore
195
- profile: { id: user.$id, ...user },
196
229
  };
197
- },
198
- async session({ session, token }) {
199
- //@ts-ignore
200
- session.user.id = token?.id;
201
- //@ts-ignore
202
- session.user = token.profile;
203
- return session;
204
- },
205
- //@ts-ignore
206
- async signIn({ user, account }) {
207
- /* if (account?.provider === "credentials" || account?.provider === "token") {
208
- // check if user's email is verified or not
209
- if (!user.emailVerified && !EMAIL_VERIFICATION_DISABLED) {
210
- throw new Error("Email Verification is Pending");
211
- }
212
- return true;
213
- }
214
- if (ENTERPRISE_LICENSE_KEY) {
215
- return handleSSOCallback({ user, account });
216
- } */
217
- return true;
218
- },
219
- },
220
- pages: {
221
- signIn: "/auth/login",
222
- signOut: "/auth/logout",
223
- error: "/auth/login", // Error code passed in query string as ?error=
224
- },
225
- };
230
+ }
231
+ return options;
232
+ };
233
+ })();
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@appconda/nextjs",
3
3
  "homepage": "https://appconda.io/support",
4
4
  "description": "Appconda is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API",
5
- "version": "1.0.86",
5
+ "version": "1.0.87",
6
6
  "license": "BSD-3-Clause",
7
7
  "main": "dist/index.js",
8
8
  "types": "dist/index.d.ts",
@@ -27,7 +27,7 @@ export const actionClient = createSafeActionClient({
27
27
  });
28
28
 
29
29
  export const authenticatedActionClient = actionClient.use(async ({ next }) => {
30
- const session = await getServerSession(authOptions);
30
+ const session = await getServerSession(authOptions());
31
31
  if (!session?.user) {
32
32
  throw new AuthenticationError("Not authenticated");
33
33
  }
@@ -2,5 +2,5 @@ import { getServerSession } from "next-auth"
2
2
  import { authOptions } from "./authOptions";
3
3
 
4
4
  export const auth = async ()=> {
5
- return await getServerSession(authOptions);
5
+ return await getServerSession(authOptions());
6
6
  }
@@ -1,20 +1,20 @@
1
- import type { NextAuthOptions } from "next-auth";
1
+ import type { NextAuthOptions } from "next-auth";
2
2
  import CredentialsProvider from "next-auth/providers/credentials";
3
3
  import { cookies } from "next/headers";
4
4
  import { getAppcondaClient } from "../getAppcondaClient";
5
5
  import { Account } from "../modules/account/service";
6
- //import { getEnv } from "../lib/env";
6
+ import { getEnv } from "../lib/env";
7
7
  import { getSDKForCurrentUser } from "../getSDKForCurrentUser";
8
8
  import { Query } from "../query";
9
9
 
10
- const getEnv = () => {
10
+ /* const getEnv = () => {
11
11
  return {
12
12
  APPCONDA_ENDPOINT: 'process.env.APPCONDA_ENDPOINT',
13
13
  APPCONDA_CLIENT_ENDPOINT: 'process.env.APPCONDA_CLIENT_ENDPOINT',
14
14
  _SERVICE_TOKEN: 'process.env._SERVICE_TOKEN',
15
15
  ENTERPRISE_LICENSE_KEY: 'process.env.ENTERPRISE_LICENSE_KEY',
16
16
  };
17
- };
17
+ }; */
18
18
 
19
19
  export async function signIn({ userName, password }: { userName: string, password: string }) {
20
20
  const adminClient = await getAppcondaClient();
@@ -36,210 +36,219 @@ export async function signIn({ userName, password }: { userName: string, passwor
36
36
 
37
37
  }
38
38
 
39
- export const authOptions: NextAuthOptions = {
40
- providers: [
41
- CredentialsProvider({
42
- id: "credentials",
43
- // The name to display on the sign in form (e.g. "Sign in with...")
44
- name: "Credentials",
45
- // The credentials is used to generate a suitable form on the sign in page.
46
- // You can specify whatever fields you are expecting to be submitted.
47
- // e.g. domain, username, password, 2FA token, etc.
48
- // You can pass any HTML attribute to the <input> tag through the object.
49
- credentials: {
50
- email: {
51
- label: "Email Address",
52
- type: "email",
53
- placeholder: "Your email address",
39
+ export const authOptions = (() => {
40
+ let options = null;
41
+
42
+ return () => {
43
+ if (options == null) {
44
+ options = {
45
+ providers: [
46
+ CredentialsProvider({
47
+ id: "credentials",
48
+ // The name to display on the sign in form (e.g. "Sign in with...")
49
+ name: "Credentials",
50
+ // The credentials is used to generate a suitable form on the sign in page.
51
+ // You can specify whatever fields you are expecting to be submitted.
52
+ // e.g. domain, username, password, 2FA token, etc.
53
+ // You can pass any HTML attribute to the <input> tag through the object.
54
+ credentials: {
55
+ email: {
56
+ label: "Email Address",
57
+ type: "email",
58
+ placeholder: "Your email address",
59
+ },
60
+ password: {
61
+ label: "Password",
62
+ type: "password",
63
+ placeholder: "Your password",
64
+ },
65
+ totpCode: { label: "Two-factor Code", type: "input", placeholder: "Code from authenticator app" },
66
+ backupCode: { label: "Backup Code", type: "input", placeholder: "Two-factor backup code" },
67
+ },
68
+ async authorize(credentials, _req) {
69
+ let user;
70
+ const appcondaSession = await signIn({ userName: credentials?.email as string, password: credentials?.password as string });
71
+
72
+ console.log(credentials);
73
+ /* try {
74
+ user = await prisma.user.findUnique({
75
+ where: {
76
+ email: credentials?.email,
77
+ },
78
+ });
79
+ } catch (e) {
80
+ console.error(e);
81
+ throw Error("Internal server error. Please try again later");
82
+ }
83
+ if (!user || !credentials) {
84
+ throw new Error("Invalid credentials");
85
+ }
86
+ if (!user.password) {
87
+ throw new Error("Invalid credentials");
88
+ }
89
+
90
+ const isValid = await verifyPassword(credentials.password, user.password);
91
+
92
+ if (!isValid) {
93
+ throw new Error("Invalid credentials");
94
+ }
95
+
96
+ if (user.twoFactorEnabled && credentials.backupCode) {
97
+ if (!ENCRYPTION_KEY) {
98
+ console.error("Missing encryption key; cannot proceed with backup code login.");
99
+ throw new Error("Internal Server Error");
100
+ }
101
+
102
+ if (!user.backupCodes) throw new Error("No backup codes found");
103
+
104
+ const backupCodes = JSON.parse(symmetricDecrypt(user.backupCodes, ENCRYPTION_KEY));
105
+
106
+ // check if user-supplied code matches one
107
+ const index = backupCodes.indexOf(credentials.backupCode.replaceAll("-", ""));
108
+ if (index === -1) throw new Error("Invalid backup code");
109
+
110
+ // delete verified backup code and re-encrypt remaining
111
+ backupCodes[index] = null;
112
+ await prisma.user.update({
113
+ where: {
114
+ id: user.id,
115
+ },
116
+ data: {
117
+ backupCodes: symmetricEncrypt(JSON.stringify(backupCodes), ENCRYPTION_KEY),
118
+ },
119
+ });
120
+ } else if (user.twoFactorEnabled) {
121
+ if (!credentials.totpCode) {
122
+ throw new Error("second factor required");
123
+ }
124
+
125
+ if (!user.twoFactorSecret) {
126
+ throw new Error("Internal Server Error");
127
+ }
128
+
129
+ if (!ENCRYPTION_KEY) {
130
+ throw new Error("Internal Server Error");
131
+ }
132
+
133
+ const secret = symmetricDecrypt(user.twoFactorSecret, ENCRYPTION_KEY);
134
+ if (secret.length !== 32) {
135
+ throw new Error("Internal Server Error");
136
+ }
137
+
138
+ const isValidToken = (await import("./totp")).totpAuthenticatorCheck(credentials.totpCode, secret);
139
+ if (!isValidToken) {
140
+ throw new Error("Invalid second factor code");
141
+ }
142
+ } */
143
+
144
+ console.log("asafdf")
145
+
146
+ return {
147
+ id: appcondaSession.userId,
148
+ email: appcondaSession.providerUid,
149
+ emailVerified: true,
150
+ imageUrl: "",
151
+ };
152
+ },
153
+ }),
154
+ CredentialsProvider({
155
+ id: "token",
156
+ // The name to display on the sign in form (e.g. "Sign in with...")
157
+ name: "Token",
158
+ // The credentials is used to generate a suitable form on the sign in page.
159
+ // You can specify whatever fields you are expecting to be submitted.
160
+ // e.g. domain, username, password, 2FA token, etc.
161
+ // You can pass any HTML attribute to the <input> tag through the object.
162
+ credentials: {
163
+ token: {
164
+ label: "Verification Token",
165
+ type: "string",
166
+ },
167
+ },
168
+ async authorize(credentials, _req) {
169
+
170
+ let user;
171
+ /* try {
172
+ if (!credentials?.token) {
173
+ throw new Error("Token not found");
174
+ }
175
+ const { id } = await verifyToken(credentials?.token);
176
+ user = await prisma.user.findUnique({
177
+ where: {
178
+ id: id,
179
+ },
180
+ });
181
+ } catch (e) {
182
+ console.error(e);
183
+ throw new Error("Either a user does not match the provided token or the token is invalid");
184
+ }
185
+
186
+ if (!user) {
187
+ throw new Error("Either a user does not match the provided token or the token is invalid");
188
+ }
189
+
190
+ if (user.emailVerified) {
191
+ throw new Error("Email already verified");
192
+ }
193
+
194
+ user = await updateUser(user.id, { emailVerified: new Date() }); */
195
+
196
+ return user || null;
197
+ },
198
+ }),
199
+ // Conditionally add enterprise SSO providers
200
+ ...(getEnv().ENTERPRISE_LICENSE_KEY ? [] : []),
201
+ ],
202
+ callbacks: {
203
+ async jwt({ token }) {
204
+
205
+ const { users } = await getSDKForCurrentUser();
206
+ const userList = await users.list([Query.equal("email", token.email!)])
207
+
208
+ const user = userList.users[0] ?? {};
209
+
210
+ /* const existingUser = await getUserByEmail(token?.email!);
211
+
212
+ if (!existingUser) {
213
+ return token;
214
+ } */
215
+
216
+ return {
217
+ ...token,
218
+ //@ts-ignore
219
+ profile: { id: user.$id, ...user },
220
+ };
221
+ },
222
+ async session({ session, token }) {
223
+ //@ts-ignore
224
+ session.user.id = token?.id;
225
+ //@ts-ignore
226
+ session.user = token.profile;
227
+
228
+ return session;
229
+ },
230
+ //@ts-ignore
231
+ async signIn({ user, account }: { user: any; account: Account | null }) {
232
+ /* if (account?.provider === "credentials" || account?.provider === "token") {
233
+ // check if user's email is verified or not
234
+ if (!user.emailVerified && !EMAIL_VERIFICATION_DISABLED) {
235
+ throw new Error("Email Verification is Pending");
236
+ }
237
+ return true;
238
+ }
239
+ if (ENTERPRISE_LICENSE_KEY) {
240
+ return handleSSOCallback({ user, account });
241
+ } */
242
+ return true;
243
+ },
54
244
  },
55
- password: {
56
- label: "Password",
57
- type: "password",
58
- placeholder: "Your password",
245
+ pages: {
246
+ signIn: "/auth/login",
247
+ signOut: "/auth/logout",
248
+ error: "/auth/login", // Error code passed in query string as ?error=
59
249
  },
60
- totpCode: { label: "Two-factor Code", type: "input", placeholder: "Code from authenticator app" },
61
- backupCode: { label: "Backup Code", type: "input", placeholder: "Two-factor backup code" },
62
- },
63
- async authorize(credentials, _req) {
64
- let user;
65
- const appcondaSession = await signIn({ userName: credentials?.email as string, password: credentials?.password as string });
66
-
67
- console.log(credentials);
68
- /* try {
69
- user = await prisma.user.findUnique({
70
- where: {
71
- email: credentials?.email,
72
- },
73
- });
74
- } catch (e) {
75
- console.error(e);
76
- throw Error("Internal server error. Please try again later");
77
- }
78
- if (!user || !credentials) {
79
- throw new Error("Invalid credentials");
80
- }
81
- if (!user.password) {
82
- throw new Error("Invalid credentials");
83
- }
84
-
85
- const isValid = await verifyPassword(credentials.password, user.password);
86
-
87
- if (!isValid) {
88
- throw new Error("Invalid credentials");
89
- }
90
-
91
- if (user.twoFactorEnabled && credentials.backupCode) {
92
- if (!ENCRYPTION_KEY) {
93
- console.error("Missing encryption key; cannot proceed with backup code login.");
94
- throw new Error("Internal Server Error");
95
- }
96
-
97
- if (!user.backupCodes) throw new Error("No backup codes found");
98
-
99
- const backupCodes = JSON.parse(symmetricDecrypt(user.backupCodes, ENCRYPTION_KEY));
100
-
101
- // check if user-supplied code matches one
102
- const index = backupCodes.indexOf(credentials.backupCode.replaceAll("-", ""));
103
- if (index === -1) throw new Error("Invalid backup code");
104
-
105
- // delete verified backup code and re-encrypt remaining
106
- backupCodes[index] = null;
107
- await prisma.user.update({
108
- where: {
109
- id: user.id,
110
- },
111
- data: {
112
- backupCodes: symmetricEncrypt(JSON.stringify(backupCodes), ENCRYPTION_KEY),
113
- },
114
- });
115
- } else if (user.twoFactorEnabled) {
116
- if (!credentials.totpCode) {
117
- throw new Error("second factor required");
118
- }
119
-
120
- if (!user.twoFactorSecret) {
121
- throw new Error("Internal Server Error");
122
- }
123
-
124
- if (!ENCRYPTION_KEY) {
125
- throw new Error("Internal Server Error");
126
- }
127
-
128
- const secret = symmetricDecrypt(user.twoFactorSecret, ENCRYPTION_KEY);
129
- if (secret.length !== 32) {
130
- throw new Error("Internal Server Error");
131
- }
132
-
133
- const isValidToken = (await import("./totp")).totpAuthenticatorCheck(credentials.totpCode, secret);
134
- if (!isValidToken) {
135
- throw new Error("Invalid second factor code");
136
- }
137
- } */
138
-
139
- console.log("asafdf")
140
-
141
- return {
142
- id: appcondaSession.userId,
143
- email: appcondaSession.providerUid,
144
- emailVerified: true,
145
- imageUrl: "",
146
- };
147
- },
148
- }),
149
- CredentialsProvider({
150
- id: "token",
151
- // The name to display on the sign in form (e.g. "Sign in with...")
152
- name: "Token",
153
- // The credentials is used to generate a suitable form on the sign in page.
154
- // You can specify whatever fields you are expecting to be submitted.
155
- // e.g. domain, username, password, 2FA token, etc.
156
- // You can pass any HTML attribute to the <input> tag through the object.
157
- credentials: {
158
- token: {
159
- label: "Verification Token",
160
- type: "string",
161
- },
162
- },
163
- async authorize(credentials, _req) {
164
-
165
- let user;
166
- /* try {
167
- if (!credentials?.token) {
168
- throw new Error("Token not found");
169
- }
170
- const { id } = await verifyToken(credentials?.token);
171
- user = await prisma.user.findUnique({
172
- where: {
173
- id: id,
174
- },
175
- });
176
- } catch (e) {
177
- console.error(e);
178
- throw new Error("Either a user does not match the provided token or the token is invalid");
179
- }
180
-
181
- if (!user) {
182
- throw new Error("Either a user does not match the provided token or the token is invalid");
183
- }
184
-
185
- if (user.emailVerified) {
186
- throw new Error("Email already verified");
187
- }
188
-
189
- user = await updateUser(user.id, { emailVerified: new Date() }); */
190
-
191
- return user || null;
192
- },
193
- }),
194
- // Conditionally add enterprise SSO providers
195
- ...(getEnv().ENTERPRISE_LICENSE_KEY ? [] : []),
196
- ],
197
- callbacks: {
198
- async jwt({ token }) {
199
-
200
- const { users } = await getSDKForCurrentUser();
201
- const userList = await users.list([Query.equal("email", token.email!)])
202
-
203
- const user = userList.users[0] ?? {};
204
-
205
- /* const existingUser = await getUserByEmail(token?.email!);
206
-
207
- if (!existingUser) {
208
- return token;
209
- } */
210
-
211
- return {
212
- ...token,
213
- //@ts-ignore
214
- profile: { id: user.$id, ...user },
215
- };
216
- },
217
- async session({ session, token }) {
218
- //@ts-ignore
219
- session.user.id = token?.id;
220
- //@ts-ignore
221
- session.user = token.profile;
222
-
223
- return session;
224
- },
225
- //@ts-ignore
226
- async signIn({ user, account }: { user: any; account: Account | null }) {
227
- /* if (account?.provider === "credentials" || account?.provider === "token") {
228
- // check if user's email is verified or not
229
- if (!user.emailVerified && !EMAIL_VERIFICATION_DISABLED) {
230
- throw new Error("Email Verification is Pending");
231
- }
232
- return true;
233
- }
234
- if (ENTERPRISE_LICENSE_KEY) {
235
- return handleSSOCallback({ user, account });
236
- } */
237
- return true;
238
- },
239
- },
240
- pages: {
241
- signIn: "/auth/login",
242
- signOut: "/auth/logout",
243
- error: "/auth/login", // Error code passed in query string as ?error=
244
- },
245
- };
250
+ }
251
+ }
252
+ return options;
253
+ }
254
+ })();