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.js
CHANGED
|
@@ -31,50 +31,6 @@ import express, {
|
|
|
31
31
|
} from "express";
|
|
32
32
|
import jwt4 from "jsonwebtoken";
|
|
33
33
|
|
|
34
|
-
// src/core/utils.ts
|
|
35
|
-
function hasRole(session, role) {
|
|
36
|
-
if (!session || !session.roles) return false;
|
|
37
|
-
return session.roles.includes(role);
|
|
38
|
-
}
|
|
39
|
-
function baseProjectCookieOptionsFrom(cookie) {
|
|
40
|
-
const base = {
|
|
41
|
-
secure: cookie.secure ?? false,
|
|
42
|
-
sameSite: cookie.sameSite ?? "lax",
|
|
43
|
-
path: cookie.path ?? "/",
|
|
44
|
-
maxAge: cookie.maxAgeMs
|
|
45
|
-
};
|
|
46
|
-
if (cookie.domain) base.domain = cookie.domain;
|
|
47
|
-
return base;
|
|
48
|
-
}
|
|
49
|
-
function hasAnyRole(session, roles) {
|
|
50
|
-
if (!session || !session.roles || !Array.isArray(roles) || roles.length === 0) {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
return roles.some((role) => session.roles.includes(role));
|
|
54
|
-
}
|
|
55
|
-
function hasAllRoles(session, roles) {
|
|
56
|
-
if (!session || !session.roles || !Array.isArray(roles) || roles.length === 0) {
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
return roles.every((role) => session.roles.includes(role));
|
|
60
|
-
}
|
|
61
|
-
function hasPermission(session, permission) {
|
|
62
|
-
if (!session || !session.permissions) return false;
|
|
63
|
-
return session.permissions.includes(permission);
|
|
64
|
-
}
|
|
65
|
-
function hasAnyPermission(session, permissions) {
|
|
66
|
-
if (!session || !session.permissions || !Array.isArray(permissions) || permissions.length === 0) {
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
return permissions.some((perm) => session.permissions.includes(perm));
|
|
70
|
-
}
|
|
71
|
-
function hasAllPermissions(session, permissions) {
|
|
72
|
-
if (!session || !session.permissions || !Array.isArray(permissions) || permissions.length === 0) {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
return permissions.every((perm) => session.permissions.includes(perm));
|
|
76
|
-
}
|
|
77
|
-
|
|
78
34
|
// src/config/loadConfig.ts
|
|
79
35
|
function loadConfig() {
|
|
80
36
|
return {
|
|
@@ -138,6 +94,63 @@ function isPlainObject(value) {
|
|
|
138
94
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
139
95
|
}
|
|
140
96
|
|
|
97
|
+
// src/core/utils.ts
|
|
98
|
+
function hasRole(session, role) {
|
|
99
|
+
if (!session || !session.roles) return false;
|
|
100
|
+
return session.roles.includes(role);
|
|
101
|
+
}
|
|
102
|
+
function baseProjectCookieOptionsFrom(cookie) {
|
|
103
|
+
const base = {
|
|
104
|
+
secure: cookie.secure ?? false,
|
|
105
|
+
sameSite: cookie.sameSite ?? "lax",
|
|
106
|
+
path: cookie.path ?? "/",
|
|
107
|
+
maxAge: cookie.maxAgeMs
|
|
108
|
+
};
|
|
109
|
+
if (cookie.domain) base.domain = cookie.domain;
|
|
110
|
+
return base;
|
|
111
|
+
}
|
|
112
|
+
function buildClearCookieOptions(cookie) {
|
|
113
|
+
const opts = {
|
|
114
|
+
httpOnly: true,
|
|
115
|
+
// not strictly required but fine
|
|
116
|
+
secure: cookie.secure ?? false,
|
|
117
|
+
sameSite: cookie.sameSite ?? "lax",
|
|
118
|
+
path: cookie.path ?? "/"
|
|
119
|
+
};
|
|
120
|
+
if (cookie.domain) {
|
|
121
|
+
opts.domain = cookie.domain;
|
|
122
|
+
}
|
|
123
|
+
return opts;
|
|
124
|
+
}
|
|
125
|
+
function hasAnyRole(session, roles) {
|
|
126
|
+
if (!session || !session.roles || !Array.isArray(roles) || roles.length === 0) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
return roles.some((role) => session.roles.includes(role));
|
|
130
|
+
}
|
|
131
|
+
function hasAllRoles(session, roles) {
|
|
132
|
+
if (!session || !session.roles || !Array.isArray(roles) || roles.length === 0) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
return roles.every((role) => session.roles.includes(role));
|
|
136
|
+
}
|
|
137
|
+
function hasPermission(session, permission) {
|
|
138
|
+
if (!session || !session.permissions) return false;
|
|
139
|
+
return session.permissions.includes(permission);
|
|
140
|
+
}
|
|
141
|
+
function hasAnyPermission(session, permissions) {
|
|
142
|
+
if (!session || !session.permissions || !Array.isArray(permissions) || permissions.length === 0) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
return permissions.some((perm) => session.permissions.includes(perm));
|
|
146
|
+
}
|
|
147
|
+
function hasAllPermissions(session, permissions) {
|
|
148
|
+
if (!session || !session.permissions || !Array.isArray(permissions) || permissions.length === 0) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
return permissions.every((perm) => session.permissions.includes(perm));
|
|
152
|
+
}
|
|
153
|
+
|
|
141
154
|
// src/core/roles.config.ts
|
|
142
155
|
var PLATFORM_ROLES = [
|
|
143
156
|
{
|
|
@@ -182,10 +195,14 @@ function buildSession(payload) {
|
|
|
182
195
|
roles: normalizedRoles,
|
|
183
196
|
permissions
|
|
184
197
|
};
|
|
198
|
+
if (payload?.firstName) session.firstName = payload.firstName;
|
|
199
|
+
if (payload?.lastName) session.lastName = payload.lastName;
|
|
185
200
|
if (payload?.projectId) session.projectId = payload.projectId;
|
|
186
201
|
if (payload?.orgId) session.orgId = payload.orgId;
|
|
187
202
|
if (payload?.org_id) session.org_id = payload.org_id;
|
|
188
203
|
if (payload?.authType) session.authType = payload.authType;
|
|
204
|
+
if (payload?.createdAt) session.createdAt = payload.createdAt;
|
|
205
|
+
if (payload?.metadata) session.metadata = payload.metadata;
|
|
189
206
|
Object.keys(payload || {}).forEach((key) => {
|
|
190
207
|
if (![
|
|
191
208
|
"sub",
|
|
@@ -239,7 +256,7 @@ var MetadataSchema = new mongoose2.Schema(
|
|
|
239
256
|
);
|
|
240
257
|
var OrgUserSchema = new mongoose2.Schema(
|
|
241
258
|
{
|
|
242
|
-
id: { type: String, default: uuid(), index: true },
|
|
259
|
+
id: { type: String, default: uuid(), index: true, unique: true },
|
|
243
260
|
email: { type: String, required: true, unique: true },
|
|
244
261
|
firstName: { type: String, required: true },
|
|
245
262
|
lastName: { type: String, required: true },
|
|
@@ -359,10 +376,14 @@ function requireAuth() {
|
|
|
359
376
|
const session = buildSession({
|
|
360
377
|
sub: user.id.toString(),
|
|
361
378
|
email: user.email,
|
|
379
|
+
firstName: user.firstName,
|
|
380
|
+
lastName: user.lastName,
|
|
381
|
+
metadata: user.metadata || [],
|
|
362
382
|
roles: user.roles || [],
|
|
363
383
|
orgId: user.orgId,
|
|
364
384
|
org_id: user.orgId,
|
|
365
|
-
projectId: user.projectId
|
|
385
|
+
projectId: user.projectId,
|
|
386
|
+
createdAt: user.createdAt
|
|
366
387
|
});
|
|
367
388
|
session.authType = "api-key";
|
|
368
389
|
session.projectId = readProjectId(req) || user.projectId || void 0;
|
|
@@ -543,14 +564,14 @@ var AuthAdminService = class {
|
|
|
543
564
|
async createUserInRealm(payload) {
|
|
544
565
|
const hashedPassword = payload.credentials?.[0]?.value ? await bcrypt.hash(payload.credentials[0].value, 10) : void 0;
|
|
545
566
|
const user = await OrgUser.create({
|
|
546
|
-
|
|
567
|
+
id: crypto.randomUUID(),
|
|
547
568
|
email: payload.email,
|
|
548
569
|
firstName: payload.firstName,
|
|
549
570
|
lastName: payload.lastName,
|
|
550
571
|
projectId: payload.projectId,
|
|
551
572
|
emailVerified: payload.emailVerified || false,
|
|
552
573
|
passwordHash: hashedPassword,
|
|
553
|
-
|
|
574
|
+
metadata: payload.metadata || []
|
|
554
575
|
});
|
|
555
576
|
return user;
|
|
556
577
|
}
|
|
@@ -638,29 +659,13 @@ var EmailService = class {
|
|
|
638
659
|
}
|
|
639
660
|
};
|
|
640
661
|
|
|
641
|
-
// src/utils/cookie.ts
|
|
642
|
-
function cookieOpts(isRefresh = false) {
|
|
643
|
-
const maxAge = isRefresh ? config.cookies.refreshTtlMs : config.cookies.accessTtlMs;
|
|
644
|
-
const secure = process.env.NODE_ENV === "production" ? process.env.COOKIE_SECURE ?? true : false;
|
|
645
|
-
return {
|
|
646
|
-
httpOnly: true,
|
|
647
|
-
secure,
|
|
648
|
-
sameSite: "none",
|
|
649
|
-
domain: process.env.COOKIE_DOMAIN,
|
|
650
|
-
maxAge
|
|
651
|
-
};
|
|
652
|
-
}
|
|
653
|
-
function clearOpts() {
|
|
654
|
-
const secure = process.env.NODE_ENV === "production" ? process.env.COOKIE_SECURE ?? true : false;
|
|
655
|
-
return {
|
|
656
|
-
domain: process.env.COOKIE_DOMAIN,
|
|
657
|
-
sameSite: "none",
|
|
658
|
-
secure
|
|
659
|
-
};
|
|
660
|
-
}
|
|
661
|
-
|
|
662
662
|
// src/express/auth.routes.ts
|
|
663
663
|
function createAuthRouter(options = {}) {
|
|
664
|
+
const googleClientId = process.env.GOOGLE_CLIENT_ID;
|
|
665
|
+
const googleClientSecret = process.env.GOOGLE_CLIENT_SECRET;
|
|
666
|
+
const googleRedirectUri = process.env.GOOGLE_REDIRECT_URI;
|
|
667
|
+
const googleDefaultRedirect = process.env.GOOGLE_DEFAULT_REDIRECT || getFrontendBaseUrl(options) || "/";
|
|
668
|
+
const isGoogleEnabled = !!googleClientId && !!googleClientSecret && !!googleRedirectUri;
|
|
664
669
|
if (options.config) {
|
|
665
670
|
configureAuthX(options.config);
|
|
666
671
|
}
|
|
@@ -685,8 +690,10 @@ function createAuthRouter(options = {}) {
|
|
|
685
690
|
);
|
|
686
691
|
r.post("/login", validateLogin, async (req, res) => {
|
|
687
692
|
const { email: emailAddress, password } = req.body || {};
|
|
693
|
+
console.log(emailAddress, password, "body");
|
|
688
694
|
try {
|
|
689
695
|
const user = await OrgUser.findOne({ email: emailAddress }).select("+password").lean();
|
|
696
|
+
console.log(user, "user");
|
|
690
697
|
if (!user) {
|
|
691
698
|
return res.status(400).json({
|
|
692
699
|
error: "Invalid email or password",
|
|
@@ -739,13 +746,13 @@ function createAuthRouter(options = {}) {
|
|
|
739
746
|
firstName,
|
|
740
747
|
lastName,
|
|
741
748
|
projectId,
|
|
742
|
-
credentials: [{ type: "password", value: password, temporary: false }]
|
|
749
|
+
credentials: [{ type: "password", value: password, temporary: false }],
|
|
750
|
+
metadata
|
|
743
751
|
});
|
|
744
752
|
await authAdmin.assignRealmRole(kcUser.id, "platform_user");
|
|
745
753
|
const user = await OrgUser.findOneAndUpdate(
|
|
746
754
|
{ email: kcUser.email },
|
|
747
755
|
{
|
|
748
|
-
id: kcUser.id,
|
|
749
756
|
email: kcUser.email,
|
|
750
757
|
firstName,
|
|
751
758
|
lastName,
|
|
@@ -785,8 +792,9 @@ function createAuthRouter(options = {}) {
|
|
|
785
792
|
return res.json(req.user || null);
|
|
786
793
|
});
|
|
787
794
|
r.post("/logout", async (_req, res) => {
|
|
788
|
-
|
|
789
|
-
res.clearCookie("
|
|
795
|
+
const clearOptions = buildClearCookieOptions(cookieConfig);
|
|
796
|
+
res.clearCookie("access_token", clearOptions);
|
|
797
|
+
res.clearCookie("refresh_token", clearOptions);
|
|
790
798
|
res.json({ ok: true });
|
|
791
799
|
});
|
|
792
800
|
r.put("/:userId/metadata", requireAuth(), async (req, res) => {
|
|
@@ -1025,16 +1033,186 @@ function createAuthRouter(options = {}) {
|
|
|
1025
1033
|
const user = await OrgUser.findOne({ email: req.query.email }).lean();
|
|
1026
1034
|
res.json(user || null);
|
|
1027
1035
|
});
|
|
1028
|
-
r.get("/google",
|
|
1029
|
-
|
|
1036
|
+
r.get("/google", (req, res) => {
|
|
1037
|
+
if (!isGoogleEnabled) {
|
|
1038
|
+
return res.status(500).json({ error: "Google login not configured" });
|
|
1039
|
+
}
|
|
1040
|
+
const state = req.query.redirectTo ? encodeURIComponent(String(req.query.redirectTo)) : "";
|
|
1041
|
+
const params = new URLSearchParams({
|
|
1042
|
+
client_id: googleClientId,
|
|
1043
|
+
redirect_uri: googleRedirectUri,
|
|
1044
|
+
response_type: "code",
|
|
1045
|
+
scope: "openid email profile",
|
|
1046
|
+
access_type: "offline",
|
|
1047
|
+
prompt: "consent",
|
|
1048
|
+
state
|
|
1049
|
+
});
|
|
1050
|
+
const url = `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`;
|
|
1051
|
+
res.redirect(url);
|
|
1030
1052
|
});
|
|
1031
|
-
r.get("/google/callback", async (
|
|
1032
|
-
|
|
1033
|
-
"
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
);
|
|
1037
|
-
|
|
1053
|
+
r.get("/google/callback", async (req, res) => {
|
|
1054
|
+
if (!isGoogleEnabled) {
|
|
1055
|
+
return res.status(500).json({ error: "Google login not configured" });
|
|
1056
|
+
}
|
|
1057
|
+
const code = String(req.query.code || "");
|
|
1058
|
+
const state = req.query.state ? String(req.query.state) : "";
|
|
1059
|
+
if (!code) {
|
|
1060
|
+
return res.status(400).json({ ok: false, error: "Missing authorization code" });
|
|
1061
|
+
}
|
|
1062
|
+
try {
|
|
1063
|
+
const tokenRes = await fetch("https://oauth2.googleapis.com/token", {
|
|
1064
|
+
method: "POST",
|
|
1065
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
1066
|
+
body: new URLSearchParams({
|
|
1067
|
+
code,
|
|
1068
|
+
client_id: googleClientId,
|
|
1069
|
+
client_secret: googleClientSecret,
|
|
1070
|
+
redirect_uri: googleRedirectUri,
|
|
1071
|
+
grant_type: "authorization_code"
|
|
1072
|
+
})
|
|
1073
|
+
});
|
|
1074
|
+
if (!tokenRes.ok) {
|
|
1075
|
+
const errJson = await tokenRes.json().catch(() => ({}));
|
|
1076
|
+
console.error("Google token error", errJson);
|
|
1077
|
+
return res.status(400).json({ ok: false, error: "Failed to exchange Google code" });
|
|
1078
|
+
}
|
|
1079
|
+
const tokenJson = await tokenRes.json();
|
|
1080
|
+
if (!tokenJson.id_token) {
|
|
1081
|
+
return res.status(400).json({ ok: false, error: "Missing id_token from Google" });
|
|
1082
|
+
}
|
|
1083
|
+
const decoded = jwt4.decode(tokenJson.id_token);
|
|
1084
|
+
const email2 = decoded?.email;
|
|
1085
|
+
if (!email2) {
|
|
1086
|
+
return res.status(400).json({ ok: false, error: "Google account has no email" });
|
|
1087
|
+
}
|
|
1088
|
+
const emailVerified = decoded.email_verified ?? true;
|
|
1089
|
+
const firstName = decoded.given_name || "";
|
|
1090
|
+
const lastName = decoded.family_name || "";
|
|
1091
|
+
let user = await OrgUser.findOne({ email: email2 }).lean();
|
|
1092
|
+
if (!user) {
|
|
1093
|
+
const created = await OrgUser.create({
|
|
1094
|
+
email: email2,
|
|
1095
|
+
firstName,
|
|
1096
|
+
lastName,
|
|
1097
|
+
emailVerified,
|
|
1098
|
+
roles: ["platform_user"],
|
|
1099
|
+
projectId: null,
|
|
1100
|
+
metadata: []
|
|
1101
|
+
// you can also store googleId: decoded.sub
|
|
1102
|
+
});
|
|
1103
|
+
user = created.toObject();
|
|
1104
|
+
}
|
|
1105
|
+
const tokens = generateTokens(user);
|
|
1106
|
+
setAuthCookies(res, tokens, cookieConfig);
|
|
1107
|
+
const redirectTo = state ? decodeURIComponent(state) : googleDefaultRedirect;
|
|
1108
|
+
res.redirect(redirectTo);
|
|
1109
|
+
} catch (err) {
|
|
1110
|
+
console.error("Google callback error", err);
|
|
1111
|
+
const redirectError = googleDefaultRedirect.includes("?") ? `${googleDefaultRedirect}&error=google_login_failed` : `${googleDefaultRedirect}?error=google_login_failed`;
|
|
1112
|
+
res.redirect(redirectError);
|
|
1113
|
+
}
|
|
1114
|
+
});
|
|
1115
|
+
r.get("/github", (req, res) => {
|
|
1116
|
+
const githubClientId = process.env.GITHUB_CLIENT_ID;
|
|
1117
|
+
const githubRedirectUri = process.env.GITHUB_REDIRECT_URI;
|
|
1118
|
+
if (!githubClientId || !githubRedirectUri) {
|
|
1119
|
+
return res.status(500).json({ error: "GitHub login not configured" });
|
|
1120
|
+
}
|
|
1121
|
+
const state = req.query.redirectTo ? encodeURIComponent(String(req.query.redirectTo)) : "";
|
|
1122
|
+
const params = new URLSearchParams({
|
|
1123
|
+
client_id: githubClientId,
|
|
1124
|
+
redirect_uri: githubRedirectUri,
|
|
1125
|
+
scope: "user:email",
|
|
1126
|
+
state,
|
|
1127
|
+
allow_signup: "true"
|
|
1128
|
+
});
|
|
1129
|
+
const url = `https://github.com/login/oauth/authorize?${params.toString()}`;
|
|
1130
|
+
res.redirect(url);
|
|
1131
|
+
});
|
|
1132
|
+
r.get("/github/callback", async (req, res) => {
|
|
1133
|
+
const githubClientId = process.env.GITHUB_CLIENT_ID;
|
|
1134
|
+
const githubClientSecret = process.env.GITHUB_CLIENT_SECRET;
|
|
1135
|
+
const githubRedirectUri = process.env.GITHUB_REDIRECT_URI;
|
|
1136
|
+
const githubDefaultRedirect = process.env.GITHUB_DEFAULT_REDIRECT || getFrontendBaseUrl(options) || "/";
|
|
1137
|
+
if (!githubClientId || !githubClientSecret || !githubRedirectUri) {
|
|
1138
|
+
return res.status(500).json({ error: "GitHub login not configured" });
|
|
1139
|
+
}
|
|
1140
|
+
const code = String(req.query.code || "");
|
|
1141
|
+
const state = req.query.state ? String(req.query.state) : "";
|
|
1142
|
+
if (!code) {
|
|
1143
|
+
return res.status(400).json({ ok: false, error: "Missing GitHub code" });
|
|
1144
|
+
}
|
|
1145
|
+
try {
|
|
1146
|
+
const tokenRes = await fetch(
|
|
1147
|
+
"https://github.com/login/oauth/access_token",
|
|
1148
|
+
{
|
|
1149
|
+
method: "POST",
|
|
1150
|
+
headers: {
|
|
1151
|
+
Accept: "application/json",
|
|
1152
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
1153
|
+
},
|
|
1154
|
+
body: new URLSearchParams({
|
|
1155
|
+
client_id: githubClientId,
|
|
1156
|
+
client_secret: githubClientSecret,
|
|
1157
|
+
code,
|
|
1158
|
+
redirect_uri: githubRedirectUri
|
|
1159
|
+
})
|
|
1160
|
+
}
|
|
1161
|
+
);
|
|
1162
|
+
const tokenJson = await tokenRes.json();
|
|
1163
|
+
if (!tokenJson.access_token) {
|
|
1164
|
+
console.error("GitHub token error:", tokenJson);
|
|
1165
|
+
return res.status(400).json({ ok: false, error: "Failed to get GitHub access token" });
|
|
1166
|
+
}
|
|
1167
|
+
const accessToken = tokenJson.access_token;
|
|
1168
|
+
const userRes = await fetch("https://api.github.com/user", {
|
|
1169
|
+
headers: {
|
|
1170
|
+
Authorization: `Bearer ${accessToken}`,
|
|
1171
|
+
Accept: "application/vnd.github+json"
|
|
1172
|
+
}
|
|
1173
|
+
});
|
|
1174
|
+
const githubUser = await userRes.json();
|
|
1175
|
+
const emailRes = await fetch("https://api.github.com/user/emails", {
|
|
1176
|
+
headers: {
|
|
1177
|
+
Authorization: `Bearer ${accessToken}`,
|
|
1178
|
+
Accept: "application/vnd.github+json"
|
|
1179
|
+
}
|
|
1180
|
+
});
|
|
1181
|
+
const emails = await emailRes.json();
|
|
1182
|
+
const primaryEmail = emails?.find(
|
|
1183
|
+
(e) => e.primary && e.verified
|
|
1184
|
+
)?.email;
|
|
1185
|
+
if (!primaryEmail) {
|
|
1186
|
+
return res.status(400).json({
|
|
1187
|
+
ok: false,
|
|
1188
|
+
error: "GitHub account has no verified email"
|
|
1189
|
+
});
|
|
1190
|
+
}
|
|
1191
|
+
const firstName = githubUser.name?.split(" ")[0] || "";
|
|
1192
|
+
const lastName = githubUser.name?.split(" ").slice(1).join(" ") || "";
|
|
1193
|
+
let user = await OrgUser.findOne({ email: primaryEmail }).lean();
|
|
1194
|
+
if (!user) {
|
|
1195
|
+
const created = await OrgUser.create({
|
|
1196
|
+
email: primaryEmail,
|
|
1197
|
+
firstName,
|
|
1198
|
+
lastName,
|
|
1199
|
+
emailVerified: true,
|
|
1200
|
+
roles: ["platform_user"],
|
|
1201
|
+
projectId: null,
|
|
1202
|
+
metadata: [],
|
|
1203
|
+
githubId: githubUser.id
|
|
1204
|
+
});
|
|
1205
|
+
user = created.toObject();
|
|
1206
|
+
}
|
|
1207
|
+
const tokens = generateTokens(user);
|
|
1208
|
+
setAuthCookies(res, tokens, cookieConfig);
|
|
1209
|
+
const redirectTo = state ? decodeURIComponent(state) : githubDefaultRedirect;
|
|
1210
|
+
res.redirect(redirectTo);
|
|
1211
|
+
} catch (err) {
|
|
1212
|
+
console.error("GitHub callback error:", err);
|
|
1213
|
+
const redirectError = githubDefaultRedirect.includes("?") ? `${githubDefaultRedirect}&error=github_login_failed` : `${githubDefaultRedirect}?error=github_login_failed`;
|
|
1214
|
+
res.redirect(redirectError);
|
|
1215
|
+
}
|
|
1038
1216
|
});
|
|
1039
1217
|
r.get("/get-users", async (req, res) => {
|
|
1040
1218
|
const user = await OrgUser.find({ projectId: req.query.projectId }).lean();
|
|
@@ -1112,6 +1290,11 @@ function generateTokens(user) {
|
|
|
1112
1290
|
orgId: user.orgId || null,
|
|
1113
1291
|
org_id: user.orgId || null,
|
|
1114
1292
|
projectId: user.projectId || null,
|
|
1293
|
+
firstName: user.firstName,
|
|
1294
|
+
lastName: user.lastName,
|
|
1295
|
+
emailVerified: user.emailVerified,
|
|
1296
|
+
createdAt: user.createdAt,
|
|
1297
|
+
metadata: user.metadata,
|
|
1115
1298
|
type: "user"
|
|
1116
1299
|
};
|
|
1117
1300
|
const accessToken = jwt4.sign(accessPayload, process.env.JWT_SECRET, {
|