aaspai-authx 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/express/index.cjs +239 -56
- package/dist/express/index.cjs.map +1 -1
- package/dist/express/index.js +239 -56
- package/dist/express/index.js.map +1 -1
- package/dist/index.cjs +265 -82
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +70 -69
- package/dist/index.d.ts +70 -69
- package/dist/index.js +265 -82
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +239 -56
- package/dist/nest/index.cjs.map +1 -1
- package/dist/nest/index.js +239 -56
- package/dist/nest/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -83,50 +83,6 @@ var import_crypto = require("crypto");
|
|
|
83
83
|
var import_express = __toESM(require("express"), 1);
|
|
84
84
|
var import_jsonwebtoken4 = __toESM(require("jsonwebtoken"), 1);
|
|
85
85
|
|
|
86
|
-
// src/core/utils.ts
|
|
87
|
-
function hasRole(session, role) {
|
|
88
|
-
if (!session || !session.roles) return false;
|
|
89
|
-
return session.roles.includes(role);
|
|
90
|
-
}
|
|
91
|
-
function baseProjectCookieOptionsFrom(cookie) {
|
|
92
|
-
const base = {
|
|
93
|
-
secure: cookie.secure ?? false,
|
|
94
|
-
sameSite: cookie.sameSite ?? "lax",
|
|
95
|
-
path: cookie.path ?? "/",
|
|
96
|
-
maxAge: cookie.maxAgeMs
|
|
97
|
-
};
|
|
98
|
-
if (cookie.domain) base.domain = cookie.domain;
|
|
99
|
-
return base;
|
|
100
|
-
}
|
|
101
|
-
function hasAnyRole(session, roles) {
|
|
102
|
-
if (!session || !session.roles || !Array.isArray(roles) || roles.length === 0) {
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
return roles.some((role) => session.roles.includes(role));
|
|
106
|
-
}
|
|
107
|
-
function hasAllRoles(session, roles) {
|
|
108
|
-
if (!session || !session.roles || !Array.isArray(roles) || roles.length === 0) {
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
return roles.every((role) => session.roles.includes(role));
|
|
112
|
-
}
|
|
113
|
-
function hasPermission(session, permission) {
|
|
114
|
-
if (!session || !session.permissions) return false;
|
|
115
|
-
return session.permissions.includes(permission);
|
|
116
|
-
}
|
|
117
|
-
function hasAnyPermission(session, permissions) {
|
|
118
|
-
if (!session || !session.permissions || !Array.isArray(permissions) || permissions.length === 0) {
|
|
119
|
-
return false;
|
|
120
|
-
}
|
|
121
|
-
return permissions.some((perm) => session.permissions.includes(perm));
|
|
122
|
-
}
|
|
123
|
-
function hasAllPermissions(session, permissions) {
|
|
124
|
-
if (!session || !session.permissions || !Array.isArray(permissions) || permissions.length === 0) {
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
return permissions.every((perm) => session.permissions.includes(perm));
|
|
128
|
-
}
|
|
129
|
-
|
|
130
86
|
// src/config/loadConfig.ts
|
|
131
87
|
function loadConfig() {
|
|
132
88
|
return {
|
|
@@ -190,6 +146,63 @@ function isPlainObject(value) {
|
|
|
190
146
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
191
147
|
}
|
|
192
148
|
|
|
149
|
+
// src/core/utils.ts
|
|
150
|
+
function hasRole(session, role) {
|
|
151
|
+
if (!session || !session.roles) return false;
|
|
152
|
+
return session.roles.includes(role);
|
|
153
|
+
}
|
|
154
|
+
function baseProjectCookieOptionsFrom(cookie) {
|
|
155
|
+
const base = {
|
|
156
|
+
secure: cookie.secure ?? false,
|
|
157
|
+
sameSite: cookie.sameSite ?? "lax",
|
|
158
|
+
path: cookie.path ?? "/",
|
|
159
|
+
maxAge: cookie.maxAgeMs
|
|
160
|
+
};
|
|
161
|
+
if (cookie.domain) base.domain = cookie.domain;
|
|
162
|
+
return base;
|
|
163
|
+
}
|
|
164
|
+
function buildClearCookieOptions(cookie) {
|
|
165
|
+
const opts = {
|
|
166
|
+
httpOnly: true,
|
|
167
|
+
// not strictly required but fine
|
|
168
|
+
secure: cookie.secure ?? false,
|
|
169
|
+
sameSite: cookie.sameSite ?? "lax",
|
|
170
|
+
path: cookie.path ?? "/"
|
|
171
|
+
};
|
|
172
|
+
if (cookie.domain) {
|
|
173
|
+
opts.domain = cookie.domain;
|
|
174
|
+
}
|
|
175
|
+
return opts;
|
|
176
|
+
}
|
|
177
|
+
function hasAnyRole(session, roles) {
|
|
178
|
+
if (!session || !session.roles || !Array.isArray(roles) || roles.length === 0) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
return roles.some((role) => session.roles.includes(role));
|
|
182
|
+
}
|
|
183
|
+
function hasAllRoles(session, roles) {
|
|
184
|
+
if (!session || !session.roles || !Array.isArray(roles) || roles.length === 0) {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
return roles.every((role) => session.roles.includes(role));
|
|
188
|
+
}
|
|
189
|
+
function hasPermission(session, permission) {
|
|
190
|
+
if (!session || !session.permissions) return false;
|
|
191
|
+
return session.permissions.includes(permission);
|
|
192
|
+
}
|
|
193
|
+
function hasAnyPermission(session, permissions) {
|
|
194
|
+
if (!session || !session.permissions || !Array.isArray(permissions) || permissions.length === 0) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
return permissions.some((perm) => session.permissions.includes(perm));
|
|
198
|
+
}
|
|
199
|
+
function hasAllPermissions(session, permissions) {
|
|
200
|
+
if (!session || !session.permissions || !Array.isArray(permissions) || permissions.length === 0) {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
return permissions.every((perm) => session.permissions.includes(perm));
|
|
204
|
+
}
|
|
205
|
+
|
|
193
206
|
// src/core/roles.config.ts
|
|
194
207
|
var PLATFORM_ROLES = [
|
|
195
208
|
{
|
|
@@ -234,10 +247,14 @@ function buildSession(payload) {
|
|
|
234
247
|
roles: normalizedRoles,
|
|
235
248
|
permissions
|
|
236
249
|
};
|
|
250
|
+
if (payload?.firstName) session.firstName = payload.firstName;
|
|
251
|
+
if (payload?.lastName) session.lastName = payload.lastName;
|
|
237
252
|
if (payload?.projectId) session.projectId = payload.projectId;
|
|
238
253
|
if (payload?.orgId) session.orgId = payload.orgId;
|
|
239
254
|
if (payload?.org_id) session.org_id = payload.org_id;
|
|
240
255
|
if (payload?.authType) session.authType = payload.authType;
|
|
256
|
+
if (payload?.createdAt) session.createdAt = payload.createdAt;
|
|
257
|
+
if (payload?.metadata) session.metadata = payload.metadata;
|
|
241
258
|
Object.keys(payload || {}).forEach((key) => {
|
|
242
259
|
if (![
|
|
243
260
|
"sub",
|
|
@@ -291,7 +308,7 @@ var MetadataSchema = new import_mongoose2.default.Schema(
|
|
|
291
308
|
);
|
|
292
309
|
var OrgUserSchema = new import_mongoose2.default.Schema(
|
|
293
310
|
{
|
|
294
|
-
id: { type: String, default: (0, import_uuid.v4)(), index: true },
|
|
311
|
+
id: { type: String, default: (0, import_uuid.v4)(), index: true, unique: true },
|
|
295
312
|
email: { type: String, required: true, unique: true },
|
|
296
313
|
firstName: { type: String, required: true },
|
|
297
314
|
lastName: { type: String, required: true },
|
|
@@ -411,10 +428,14 @@ function requireAuth() {
|
|
|
411
428
|
const session = buildSession({
|
|
412
429
|
sub: user.id.toString(),
|
|
413
430
|
email: user.email,
|
|
431
|
+
firstName: user.firstName,
|
|
432
|
+
lastName: user.lastName,
|
|
433
|
+
metadata: user.metadata || [],
|
|
414
434
|
roles: user.roles || [],
|
|
415
435
|
orgId: user.orgId,
|
|
416
436
|
org_id: user.orgId,
|
|
417
|
-
projectId: user.projectId
|
|
437
|
+
projectId: user.projectId,
|
|
438
|
+
createdAt: user.createdAt
|
|
418
439
|
});
|
|
419
440
|
session.authType = "api-key";
|
|
420
441
|
session.projectId = readProjectId(req) || user.projectId || void 0;
|
|
@@ -595,14 +616,14 @@ var AuthAdminService = class {
|
|
|
595
616
|
async createUserInRealm(payload) {
|
|
596
617
|
const hashedPassword = payload.credentials?.[0]?.value ? await import_bcrypt.default.hash(payload.credentials[0].value, 10) : void 0;
|
|
597
618
|
const user = await OrgUser.create({
|
|
598
|
-
|
|
619
|
+
id: crypto.randomUUID(),
|
|
599
620
|
email: payload.email,
|
|
600
621
|
firstName: payload.firstName,
|
|
601
622
|
lastName: payload.lastName,
|
|
602
623
|
projectId: payload.projectId,
|
|
603
624
|
emailVerified: payload.emailVerified || false,
|
|
604
625
|
passwordHash: hashedPassword,
|
|
605
|
-
|
|
626
|
+
metadata: payload.metadata || []
|
|
606
627
|
});
|
|
607
628
|
return user;
|
|
608
629
|
}
|
|
@@ -690,29 +711,13 @@ var EmailService = class {
|
|
|
690
711
|
}
|
|
691
712
|
};
|
|
692
713
|
|
|
693
|
-
// src/utils/cookie.ts
|
|
694
|
-
function cookieOpts(isRefresh = false) {
|
|
695
|
-
const maxAge = isRefresh ? config.cookies.refreshTtlMs : config.cookies.accessTtlMs;
|
|
696
|
-
const secure = process.env.NODE_ENV === "production" ? process.env.COOKIE_SECURE ?? true : false;
|
|
697
|
-
return {
|
|
698
|
-
httpOnly: true,
|
|
699
|
-
secure,
|
|
700
|
-
sameSite: "none",
|
|
701
|
-
domain: process.env.COOKIE_DOMAIN,
|
|
702
|
-
maxAge
|
|
703
|
-
};
|
|
704
|
-
}
|
|
705
|
-
function clearOpts() {
|
|
706
|
-
const secure = process.env.NODE_ENV === "production" ? process.env.COOKIE_SECURE ?? true : false;
|
|
707
|
-
return {
|
|
708
|
-
domain: process.env.COOKIE_DOMAIN,
|
|
709
|
-
sameSite: "none",
|
|
710
|
-
secure
|
|
711
|
-
};
|
|
712
|
-
}
|
|
713
|
-
|
|
714
714
|
// src/express/auth.routes.ts
|
|
715
715
|
function createAuthRouter(options = {}) {
|
|
716
|
+
const googleClientId = process.env.GOOGLE_CLIENT_ID;
|
|
717
|
+
const googleClientSecret = process.env.GOOGLE_CLIENT_SECRET;
|
|
718
|
+
const googleRedirectUri = process.env.GOOGLE_REDIRECT_URI;
|
|
719
|
+
const googleDefaultRedirect = process.env.GOOGLE_DEFAULT_REDIRECT || getFrontendBaseUrl(options) || "/";
|
|
720
|
+
const isGoogleEnabled = !!googleClientId && !!googleClientSecret && !!googleRedirectUri;
|
|
716
721
|
if (options.config) {
|
|
717
722
|
configureAuthX(options.config);
|
|
718
723
|
}
|
|
@@ -737,8 +742,10 @@ function createAuthRouter(options = {}) {
|
|
|
737
742
|
);
|
|
738
743
|
r.post("/login", validateLogin, async (req, res) => {
|
|
739
744
|
const { email: emailAddress, password } = req.body || {};
|
|
745
|
+
console.log(emailAddress, password, "body");
|
|
740
746
|
try {
|
|
741
747
|
const user = await OrgUser.findOne({ email: emailAddress }).select("+password").lean();
|
|
748
|
+
console.log(user, "user");
|
|
742
749
|
if (!user) {
|
|
743
750
|
return res.status(400).json({
|
|
744
751
|
error: "Invalid email or password",
|
|
@@ -791,13 +798,13 @@ function createAuthRouter(options = {}) {
|
|
|
791
798
|
firstName,
|
|
792
799
|
lastName,
|
|
793
800
|
projectId,
|
|
794
|
-
credentials: [{ type: "password", value: password, temporary: false }]
|
|
801
|
+
credentials: [{ type: "password", value: password, temporary: false }],
|
|
802
|
+
metadata
|
|
795
803
|
});
|
|
796
804
|
await authAdmin.assignRealmRole(kcUser.id, "platform_user");
|
|
797
805
|
const user = await OrgUser.findOneAndUpdate(
|
|
798
806
|
{ email: kcUser.email },
|
|
799
807
|
{
|
|
800
|
-
id: kcUser.id,
|
|
801
808
|
email: kcUser.email,
|
|
802
809
|
firstName,
|
|
803
810
|
lastName,
|
|
@@ -837,8 +844,9 @@ function createAuthRouter(options = {}) {
|
|
|
837
844
|
return res.json(req.user || null);
|
|
838
845
|
});
|
|
839
846
|
r.post("/logout", async (_req, res) => {
|
|
840
|
-
|
|
841
|
-
res.clearCookie("
|
|
847
|
+
const clearOptions = buildClearCookieOptions(cookieConfig);
|
|
848
|
+
res.clearCookie("access_token", clearOptions);
|
|
849
|
+
res.clearCookie("refresh_token", clearOptions);
|
|
842
850
|
res.json({ ok: true });
|
|
843
851
|
});
|
|
844
852
|
r.put("/:userId/metadata", requireAuth(), async (req, res) => {
|
|
@@ -1077,16 +1085,186 @@ function createAuthRouter(options = {}) {
|
|
|
1077
1085
|
const user = await OrgUser.findOne({ email: req.query.email }).lean();
|
|
1078
1086
|
res.json(user || null);
|
|
1079
1087
|
});
|
|
1080
|
-
r.get("/google",
|
|
1081
|
-
|
|
1088
|
+
r.get("/google", (req, res) => {
|
|
1089
|
+
if (!isGoogleEnabled) {
|
|
1090
|
+
return res.status(500).json({ error: "Google login not configured" });
|
|
1091
|
+
}
|
|
1092
|
+
const state = req.query.redirectTo ? encodeURIComponent(String(req.query.redirectTo)) : "";
|
|
1093
|
+
const params = new URLSearchParams({
|
|
1094
|
+
client_id: googleClientId,
|
|
1095
|
+
redirect_uri: googleRedirectUri,
|
|
1096
|
+
response_type: "code",
|
|
1097
|
+
scope: "openid email profile",
|
|
1098
|
+
access_type: "offline",
|
|
1099
|
+
prompt: "consent",
|
|
1100
|
+
state
|
|
1101
|
+
});
|
|
1102
|
+
const url = `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`;
|
|
1103
|
+
res.redirect(url);
|
|
1082
1104
|
});
|
|
1083
|
-
r.get("/google/callback", async (
|
|
1084
|
-
|
|
1085
|
-
"
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
);
|
|
1089
|
-
|
|
1105
|
+
r.get("/google/callback", async (req, res) => {
|
|
1106
|
+
if (!isGoogleEnabled) {
|
|
1107
|
+
return res.status(500).json({ error: "Google login not configured" });
|
|
1108
|
+
}
|
|
1109
|
+
const code = String(req.query.code || "");
|
|
1110
|
+
const state = req.query.state ? String(req.query.state) : "";
|
|
1111
|
+
if (!code) {
|
|
1112
|
+
return res.status(400).json({ ok: false, error: "Missing authorization code" });
|
|
1113
|
+
}
|
|
1114
|
+
try {
|
|
1115
|
+
const tokenRes = await fetch("https://oauth2.googleapis.com/token", {
|
|
1116
|
+
method: "POST",
|
|
1117
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
1118
|
+
body: new URLSearchParams({
|
|
1119
|
+
code,
|
|
1120
|
+
client_id: googleClientId,
|
|
1121
|
+
client_secret: googleClientSecret,
|
|
1122
|
+
redirect_uri: googleRedirectUri,
|
|
1123
|
+
grant_type: "authorization_code"
|
|
1124
|
+
})
|
|
1125
|
+
});
|
|
1126
|
+
if (!tokenRes.ok) {
|
|
1127
|
+
const errJson = await tokenRes.json().catch(() => ({}));
|
|
1128
|
+
console.error("Google token error", errJson);
|
|
1129
|
+
return res.status(400).json({ ok: false, error: "Failed to exchange Google code" });
|
|
1130
|
+
}
|
|
1131
|
+
const tokenJson = await tokenRes.json();
|
|
1132
|
+
if (!tokenJson.id_token) {
|
|
1133
|
+
return res.status(400).json({ ok: false, error: "Missing id_token from Google" });
|
|
1134
|
+
}
|
|
1135
|
+
const decoded = import_jsonwebtoken4.default.decode(tokenJson.id_token);
|
|
1136
|
+
const email2 = decoded?.email;
|
|
1137
|
+
if (!email2) {
|
|
1138
|
+
return res.status(400).json({ ok: false, error: "Google account has no email" });
|
|
1139
|
+
}
|
|
1140
|
+
const emailVerified = decoded.email_verified ?? true;
|
|
1141
|
+
const firstName = decoded.given_name || "";
|
|
1142
|
+
const lastName = decoded.family_name || "";
|
|
1143
|
+
let user = await OrgUser.findOne({ email: email2 }).lean();
|
|
1144
|
+
if (!user) {
|
|
1145
|
+
const created = await OrgUser.create({
|
|
1146
|
+
email: email2,
|
|
1147
|
+
firstName,
|
|
1148
|
+
lastName,
|
|
1149
|
+
emailVerified,
|
|
1150
|
+
roles: ["platform_user"],
|
|
1151
|
+
projectId: null,
|
|
1152
|
+
metadata: []
|
|
1153
|
+
// you can also store googleId: decoded.sub
|
|
1154
|
+
});
|
|
1155
|
+
user = created.toObject();
|
|
1156
|
+
}
|
|
1157
|
+
const tokens = generateTokens(user);
|
|
1158
|
+
setAuthCookies(res, tokens, cookieConfig);
|
|
1159
|
+
const redirectTo = state ? decodeURIComponent(state) : googleDefaultRedirect;
|
|
1160
|
+
res.redirect(redirectTo);
|
|
1161
|
+
} catch (err) {
|
|
1162
|
+
console.error("Google callback error", err);
|
|
1163
|
+
const redirectError = googleDefaultRedirect.includes("?") ? `${googleDefaultRedirect}&error=google_login_failed` : `${googleDefaultRedirect}?error=google_login_failed`;
|
|
1164
|
+
res.redirect(redirectError);
|
|
1165
|
+
}
|
|
1166
|
+
});
|
|
1167
|
+
r.get("/github", (req, res) => {
|
|
1168
|
+
const githubClientId = process.env.GITHUB_CLIENT_ID;
|
|
1169
|
+
const githubRedirectUri = process.env.GITHUB_REDIRECT_URI;
|
|
1170
|
+
if (!githubClientId || !githubRedirectUri) {
|
|
1171
|
+
return res.status(500).json({ error: "GitHub login not configured" });
|
|
1172
|
+
}
|
|
1173
|
+
const state = req.query.redirectTo ? encodeURIComponent(String(req.query.redirectTo)) : "";
|
|
1174
|
+
const params = new URLSearchParams({
|
|
1175
|
+
client_id: githubClientId,
|
|
1176
|
+
redirect_uri: githubRedirectUri,
|
|
1177
|
+
scope: "user:email",
|
|
1178
|
+
state,
|
|
1179
|
+
allow_signup: "true"
|
|
1180
|
+
});
|
|
1181
|
+
const url = `https://github.com/login/oauth/authorize?${params.toString()}`;
|
|
1182
|
+
res.redirect(url);
|
|
1183
|
+
});
|
|
1184
|
+
r.get("/github/callback", async (req, res) => {
|
|
1185
|
+
const githubClientId = process.env.GITHUB_CLIENT_ID;
|
|
1186
|
+
const githubClientSecret = process.env.GITHUB_CLIENT_SECRET;
|
|
1187
|
+
const githubRedirectUri = process.env.GITHUB_REDIRECT_URI;
|
|
1188
|
+
const githubDefaultRedirect = process.env.GITHUB_DEFAULT_REDIRECT || getFrontendBaseUrl(options) || "/";
|
|
1189
|
+
if (!githubClientId || !githubClientSecret || !githubRedirectUri) {
|
|
1190
|
+
return res.status(500).json({ error: "GitHub login not configured" });
|
|
1191
|
+
}
|
|
1192
|
+
const code = String(req.query.code || "");
|
|
1193
|
+
const state = req.query.state ? String(req.query.state) : "";
|
|
1194
|
+
if (!code) {
|
|
1195
|
+
return res.status(400).json({ ok: false, error: "Missing GitHub code" });
|
|
1196
|
+
}
|
|
1197
|
+
try {
|
|
1198
|
+
const tokenRes = await fetch(
|
|
1199
|
+
"https://github.com/login/oauth/access_token",
|
|
1200
|
+
{
|
|
1201
|
+
method: "POST",
|
|
1202
|
+
headers: {
|
|
1203
|
+
Accept: "application/json",
|
|
1204
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
1205
|
+
},
|
|
1206
|
+
body: new URLSearchParams({
|
|
1207
|
+
client_id: githubClientId,
|
|
1208
|
+
client_secret: githubClientSecret,
|
|
1209
|
+
code,
|
|
1210
|
+
redirect_uri: githubRedirectUri
|
|
1211
|
+
})
|
|
1212
|
+
}
|
|
1213
|
+
);
|
|
1214
|
+
const tokenJson = await tokenRes.json();
|
|
1215
|
+
if (!tokenJson.access_token) {
|
|
1216
|
+
console.error("GitHub token error:", tokenJson);
|
|
1217
|
+
return res.status(400).json({ ok: false, error: "Failed to get GitHub access token" });
|
|
1218
|
+
}
|
|
1219
|
+
const accessToken = tokenJson.access_token;
|
|
1220
|
+
const userRes = await fetch("https://api.github.com/user", {
|
|
1221
|
+
headers: {
|
|
1222
|
+
Authorization: `Bearer ${accessToken}`,
|
|
1223
|
+
Accept: "application/vnd.github+json"
|
|
1224
|
+
}
|
|
1225
|
+
});
|
|
1226
|
+
const githubUser = await userRes.json();
|
|
1227
|
+
const emailRes = await fetch("https://api.github.com/user/emails", {
|
|
1228
|
+
headers: {
|
|
1229
|
+
Authorization: `Bearer ${accessToken}`,
|
|
1230
|
+
Accept: "application/vnd.github+json"
|
|
1231
|
+
}
|
|
1232
|
+
});
|
|
1233
|
+
const emails = await emailRes.json();
|
|
1234
|
+
const primaryEmail = emails?.find(
|
|
1235
|
+
(e) => e.primary && e.verified
|
|
1236
|
+
)?.email;
|
|
1237
|
+
if (!primaryEmail) {
|
|
1238
|
+
return res.status(400).json({
|
|
1239
|
+
ok: false,
|
|
1240
|
+
error: "GitHub account has no verified email"
|
|
1241
|
+
});
|
|
1242
|
+
}
|
|
1243
|
+
const firstName = githubUser.name?.split(" ")[0] || "";
|
|
1244
|
+
const lastName = githubUser.name?.split(" ").slice(1).join(" ") || "";
|
|
1245
|
+
let user = await OrgUser.findOne({ email: primaryEmail }).lean();
|
|
1246
|
+
if (!user) {
|
|
1247
|
+
const created = await OrgUser.create({
|
|
1248
|
+
email: primaryEmail,
|
|
1249
|
+
firstName,
|
|
1250
|
+
lastName,
|
|
1251
|
+
emailVerified: true,
|
|
1252
|
+
roles: ["platform_user"],
|
|
1253
|
+
projectId: null,
|
|
1254
|
+
metadata: [],
|
|
1255
|
+
githubId: githubUser.id
|
|
1256
|
+
});
|
|
1257
|
+
user = created.toObject();
|
|
1258
|
+
}
|
|
1259
|
+
const tokens = generateTokens(user);
|
|
1260
|
+
setAuthCookies(res, tokens, cookieConfig);
|
|
1261
|
+
const redirectTo = state ? decodeURIComponent(state) : githubDefaultRedirect;
|
|
1262
|
+
res.redirect(redirectTo);
|
|
1263
|
+
} catch (err) {
|
|
1264
|
+
console.error("GitHub callback error:", err);
|
|
1265
|
+
const redirectError = githubDefaultRedirect.includes("?") ? `${githubDefaultRedirect}&error=github_login_failed` : `${githubDefaultRedirect}?error=github_login_failed`;
|
|
1266
|
+
res.redirect(redirectError);
|
|
1267
|
+
}
|
|
1090
1268
|
});
|
|
1091
1269
|
r.get("/get-users", async (req, res) => {
|
|
1092
1270
|
const user = await OrgUser.find({ projectId: req.query.projectId }).lean();
|
|
@@ -1164,6 +1342,11 @@ function generateTokens(user) {
|
|
|
1164
1342
|
orgId: user.orgId || null,
|
|
1165
1343
|
org_id: user.orgId || null,
|
|
1166
1344
|
projectId: user.projectId || null,
|
|
1345
|
+
firstName: user.firstName,
|
|
1346
|
+
lastName: user.lastName,
|
|
1347
|
+
emailVerified: user.emailVerified,
|
|
1348
|
+
createdAt: user.createdAt,
|
|
1349
|
+
metadata: user.metadata,
|
|
1167
1350
|
type: "user"
|
|
1168
1351
|
};
|
|
1169
1352
|
const accessToken = import_jsonwebtoken4.default.sign(accessPayload, process.env.JWT_SECRET, {
|