mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-21 22:59:07 +00:00
update deps
This commit is contained in:
parent
469e06280a
commit
9f76748037
86
Accounts/package-lock.json
generated
86
Accounts/package-lock.json
generated
@ -35,19 +35,19 @@
|
||||
}
|
||||
},
|
||||
"../Common": {
|
||||
"name": "common",
|
||||
"name": "@oneuptime/common",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"axios": "^1.6.7",
|
||||
"axios": "^1.6.8",
|
||||
"crypto-js": "^4.1.1",
|
||||
"json5": "^2.2.3",
|
||||
"moment": "^2.30.1",
|
||||
"moment-timezone": "^0.5.45",
|
||||
"posthog-js": "^1.104.4",
|
||||
"reflect-metadata": "^0.2.1",
|
||||
"posthog-js": "^1.116.6",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"slugify": "^1.6.5",
|
||||
"typeorm": "^0.3.20",
|
||||
"uuid": "^8.3.2"
|
||||
@ -61,49 +61,46 @@
|
||||
}
|
||||
},
|
||||
"../CommonServer": {
|
||||
"name": "common-server",
|
||||
"name": "@oneuptime/common-server",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@clickhouse/client": "^0.2.7",
|
||||
"@elastic/elasticsearch": "^8.11.0",
|
||||
"@clickhouse/client": "^0.2.10",
|
||||
"@elastic/elasticsearch": "^8.12.1",
|
||||
"@opentelemetry/api": "^1.7.0",
|
||||
"@opentelemetry/api-logs": "^0.48.0",
|
||||
"@opentelemetry/exporter-logs-otlp-http": "^0.48.0",
|
||||
"@opentelemetry/exporter-metrics-otlp-proto": "^0.48.0",
|
||||
"@opentelemetry/exporter-trace-otlp-proto": "^0.48.0",
|
||||
"@opentelemetry/api-logs": "^0.49.1",
|
||||
"@opentelemetry/auto-instrumentations-node": "^0.43.0",
|
||||
"@opentelemetry/exporter-logs-otlp-http": "^0.49.1",
|
||||
"@opentelemetry/exporter-metrics-otlp-proto": "^0.49.1",
|
||||
"@opentelemetry/exporter-trace-otlp-proto": "^0.49.1",
|
||||
"@opentelemetry/id-generator-aws-xray": "^1.2.1",
|
||||
"@opentelemetry/instrumentation-express": "^0.35.0",
|
||||
"@opentelemetry/instrumentation-http": "^0.48.0",
|
||||
"@opentelemetry/sdk-logs": "^0.48.0",
|
||||
"@opentelemetry/sdk-logs": "^0.49.1",
|
||||
"@opentelemetry/sdk-metrics": "^1.21.0",
|
||||
"@opentelemetry/sdk-node": "^0.48.0",
|
||||
"@opentelemetry/sdk-trace-node": "^1.21.0",
|
||||
"@socket.io/redis-adapter": "^8.2.1",
|
||||
"acme-client": "^5.3.0",
|
||||
"airtable": "^0.12.2",
|
||||
"axios": "^1.6.4",
|
||||
"bullmq": "^5.3.3",
|
||||
"Common": "file:../Common",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"cors": "^2.8.5",
|
||||
"cron-parser": "^4.8.1",
|
||||
"dotenv": "^16.4.1",
|
||||
"ejs": "^3.1.8",
|
||||
"express": "^4.17.3",
|
||||
"dotenv": "^16.4.4",
|
||||
"ejs": "^3.1.10",
|
||||
"express": "^4.19.2",
|
||||
"ioredis": "^5.3.2",
|
||||
"json2csv": "^5.0.7",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"markdown-it": "^13.0.1",
|
||||
"Model": "file:../Model",
|
||||
"node-cron": "^3.0.3",
|
||||
"nodemailer": "^6.9.9",
|
||||
"nodemailer": "^6.9.10",
|
||||
"pg": "^8.7.3",
|
||||
"socket.io": "^4.7.2",
|
||||
"socket.io": "^4.7.4",
|
||||
"stripe": "^10.17.0",
|
||||
"twilio": "^4.19.3",
|
||||
"twilio": "^4.22.0",
|
||||
"typeorm": "^0.3.20",
|
||||
"typeorm-extension": "^2.2.13",
|
||||
"vm2": "^3.9.14"
|
||||
"typeorm-extension": "^2.2.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^6.3.1",
|
||||
@ -124,43 +121,48 @@
|
||||
}
|
||||
},
|
||||
"../CommonUI": {
|
||||
"name": "common-ui",
|
||||
"name": "@oneuptime/common-ui",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.24.1",
|
||||
"@monaco-editor/react": "^4.4.6",
|
||||
"@opentelemetry/api": "^1.7.0",
|
||||
"@opentelemetry/context-zone": "^1.21.0",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "^0.48.0",
|
||||
"@opentelemetry/instrumentation": "^0.48.0",
|
||||
"@opentelemetry/instrumentation-fetch": "^0.48.0",
|
||||
"@opentelemetry/instrumentation-xml-http-request": "^0.48.0",
|
||||
"@nivo/core": "^0.85.1",
|
||||
"@nivo/line": "^0.85.1",
|
||||
"@opentelemetry/api": "^1.8.0",
|
||||
"@opentelemetry/context-zone": "^1.22.0",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "^0.49.1",
|
||||
"@opentelemetry/instrumentation": "^0.49.1",
|
||||
"@opentelemetry/instrumentation-fetch": "^0.49.1",
|
||||
"@opentelemetry/instrumentation-xml-http-request": "^0.49.1",
|
||||
"@opentelemetry/resources": "^1.21.0",
|
||||
"@opentelemetry/sdk-trace-web": "^1.21.0",
|
||||
"@opentelemetry/semantic-conventions": "^1.21.0",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
"@types/react-highlight": "^0.12.8",
|
||||
"Common": "file:../Common",
|
||||
"formik": "^2.2.9",
|
||||
"history": "^5.3.0",
|
||||
"lodash": "^4.17.21",
|
||||
"Model": "file:../Model",
|
||||
"moment-timezone": "^0.5.44",
|
||||
"moment-timezone": "^0.5.45",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^18.2.0",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
"react-big-calendar": "^1.8.7",
|
||||
"react-big-calendar": "^1.11.2",
|
||||
"react-color": "^2.19.3",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-dropzone": "^14.2.2",
|
||||
"react-error-boundary": "^4.0.12",
|
||||
"react-error-boundary": "^4.0.13",
|
||||
"react-highlight": "^0.15.0",
|
||||
"react-markdown": "^8.0.3",
|
||||
"react-router-dom": "^6.21.3",
|
||||
"react-router-dom": "^6.22.3",
|
||||
"react-select": "^5.4.0",
|
||||
"react-spinners": "^0.13.6",
|
||||
"react-toggle": "^4.1.3",
|
||||
"reactflow": "^11.10.3",
|
||||
"reactflow": "^11.10.4",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"socket.io-client": "^4.7.4",
|
||||
"socket.io-client": "^4.7.5",
|
||||
"tippy.js": "^6.3.7",
|
||||
"universal-cookie": "^4.0.4",
|
||||
"use-async-effect": "^2.2.6"
|
||||
@ -186,9 +188,9 @@
|
||||
}
|
||||
},
|
||||
"../Model": {
|
||||
"name": "model",
|
||||
"name": "@oneuptime/model",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"Common": "file:../Common",
|
||||
"typeorm": "^0.3.20"
|
||||
|
@ -99,303 +99,317 @@ router.get(
|
||||
}
|
||||
);
|
||||
|
||||
router.get(
|
||||
'/idp-login/:projectId/:projectSsoId',
|
||||
async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {
|
||||
return await loginUserWithSso(req, res);
|
||||
});
|
||||
|
||||
router.post(
|
||||
'/idp-login/:projectId/:projectSsoId',
|
||||
async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {
|
||||
try {
|
||||
const samlResponseBase64: string = req.body.SAMLResponse;
|
||||
return await loginUserWithSso(req, res);
|
||||
}
|
||||
);
|
||||
|
||||
const samlResponse: string = Buffer.from(
|
||||
samlResponseBase64,
|
||||
'base64'
|
||||
).toString();
|
||||
const loginUserWithSso = async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {
|
||||
try {
|
||||
|
||||
const response: JSONObject = await xml2js.parseStringPromise(
|
||||
samlResponse
|
||||
debugger;
|
||||
const samlResponseBase64: string = req.body.SAMLResponse;
|
||||
|
||||
const samlResponse: string = Buffer.from(
|
||||
samlResponseBase64,
|
||||
'base64'
|
||||
).toString();
|
||||
|
||||
const response: JSONObject = await xml2js.parseStringPromise(
|
||||
samlResponse
|
||||
);
|
||||
|
||||
let issuerUrl: string = '';
|
||||
let email: Email | null = null;
|
||||
|
||||
if (!req.params['projectId']) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadRequestException('Project ID not found')
|
||||
);
|
||||
}
|
||||
|
||||
let issuerUrl: string = '';
|
||||
let email: Email | null = null;
|
||||
if (!req.params['projectSsoId']) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadRequestException('Project SSO ID not found')
|
||||
);
|
||||
}
|
||||
|
||||
if (!req.params['projectId']) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadRequestException('Project ID not found')
|
||||
);
|
||||
}
|
||||
|
||||
if (!req.params['projectSsoId']) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadRequestException('Project SSO ID not found')
|
||||
);
|
||||
}
|
||||
|
||||
const projectSSO: ProjectSSO | null =
|
||||
await ProjectSSOService.findOneBy({
|
||||
query: {
|
||||
projectId: new ObjectID(req.params['projectId']),
|
||||
_id: req.params['projectSsoId'],
|
||||
isEnabled: true,
|
||||
},
|
||||
select: {
|
||||
signOnURL: true,
|
||||
issuerURL: true,
|
||||
publicCertificate: true,
|
||||
teams: {
|
||||
_id: true,
|
||||
},
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!projectSSO) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadRequestException('SSO Config not found')
|
||||
);
|
||||
}
|
||||
|
||||
// redirect to Identity Provider.
|
||||
|
||||
if (!projectSSO.issuerURL) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadRequestException('Issuer URL not found')
|
||||
);
|
||||
}
|
||||
|
||||
// redirect to Identity Provider.
|
||||
|
||||
if (!projectSSO.signOnURL) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadRequestException('Sign on URL not found')
|
||||
);
|
||||
}
|
||||
|
||||
if (!projectSSO.publicCertificate) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadRequestException('Public Certificate not found')
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
SSOUtil.isPayloadValid(response);
|
||||
|
||||
if (
|
||||
!SSOUtil.isSignatureValid(
|
||||
samlResponse,
|
||||
projectSSO.publicCertificate
|
||||
)
|
||||
) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadRequestException(
|
||||
'Signature is not valid or Public Certificate configured with this SSO provider is not valid'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
issuerUrl = SSOUtil.getIssuer(response);
|
||||
email = SSOUtil.getEmail(response);
|
||||
} catch (err: unknown) {
|
||||
if (err instanceof Exception) {
|
||||
return Response.sendErrorResponse(req, res, err);
|
||||
}
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new ServerException()
|
||||
);
|
||||
}
|
||||
|
||||
if (projectSSO.issuerURL.toString() !== issuerUrl) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadRequestException('Issuer URL does not match')
|
||||
);
|
||||
}
|
||||
|
||||
// Check if he already belongs to the project, If he does - then log in.
|
||||
|
||||
let alreadySavedUser: User | null = await UserService.findOneBy({
|
||||
query: { email: email },
|
||||
const projectSSO: ProjectSSO | null =
|
||||
await ProjectSSOService.findOneBy({
|
||||
query: {
|
||||
projectId: new ObjectID(req.params['projectId']),
|
||||
_id: req.params['projectSsoId'],
|
||||
isEnabled: true,
|
||||
},
|
||||
select: {
|
||||
_id: true,
|
||||
name: true,
|
||||
email: true,
|
||||
isMasterAdmin: true,
|
||||
isEmailVerified: true,
|
||||
profilePictureId: true,
|
||||
signOnURL: true,
|
||||
issuerURL: true,
|
||||
publicCertificate: true,
|
||||
teams: {
|
||||
_id: true,
|
||||
},
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
let isNewUser: boolean = false;
|
||||
|
||||
if (!alreadySavedUser) {
|
||||
// this should never happen because user is logged in before he signs in with SSO UNLESS he initiates the login though the IDP.
|
||||
|
||||
/// Create a user.
|
||||
|
||||
alreadySavedUser = await UserService.createByEmail(email, {
|
||||
isRoot: true,
|
||||
});
|
||||
|
||||
isNewUser = true;
|
||||
}
|
||||
|
||||
// If he does not then add him to teams that he should belong and log in.
|
||||
if (!alreadySavedUser.isEmailVerified && !isNewUser) {
|
||||
await AuthenticationEmail.sendVerificationEmail(
|
||||
alreadySavedUser
|
||||
);
|
||||
|
||||
return Response.render(
|
||||
req,
|
||||
res,
|
||||
'/usr/src/app/FeatureSet/Identity/Views/Message.ejs',
|
||||
{
|
||||
title: 'Email not verified.',
|
||||
message:
|
||||
'Email is not verified. We have sent you an email with the verification link. Please do not forget to check spam.',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// check if the user already belongs to the project
|
||||
const teamMemberCount: PositiveNumber =
|
||||
await TeamMemberService.countBy({
|
||||
query: {
|
||||
projectId: new ObjectID(
|
||||
req.params['projectId'] as string
|
||||
),
|
||||
userId: alreadySavedUser.id!,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (teamMemberCount.toNumber() === 0) {
|
||||
// user not in project, add him to default teams.
|
||||
|
||||
if (!projectSSO.teams || projectSSO.teams.length === 0) {
|
||||
return Response.render(
|
||||
req,
|
||||
res,
|
||||
'/usr/src/app/FeatureSet/Identity/Views/Message.ejs',
|
||||
{
|
||||
title: 'No teams added.',
|
||||
message:
|
||||
'No teams have been added to this SSO config. Please contact your admin and have default teams added.',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
for (const team of projectSSO.teams) {
|
||||
// add user to team
|
||||
let teamMember: TeamMember = new TeamMember();
|
||||
teamMember.projectId = new ObjectID(
|
||||
req.params['projectId'] as string
|
||||
);
|
||||
teamMember.userId = alreadySavedUser.id!;
|
||||
teamMember.hasAcceptedInvitation = true;
|
||||
teamMember.invitationAcceptedAt =
|
||||
OneUptimeDate.getCurrentDate();
|
||||
teamMember.teamId = team.id!;
|
||||
|
||||
teamMember = await TeamMemberService.create({
|
||||
data: teamMember,
|
||||
props: {
|
||||
isRoot: true,
|
||||
ignoreHooks: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (isNewUser) {
|
||||
return Response.render(
|
||||
req,
|
||||
res,
|
||||
'/usr/src/app/FeatureSet/Identity/Views/Message.ejs',
|
||||
{
|
||||
title: 'You have not signed up so far.',
|
||||
message:
|
||||
'You need to sign up for an account on OneUptime with this email:' +
|
||||
email.toString() +
|
||||
'. Once you have signed up, you can use SSO to log in to your project.',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const projectId: ObjectID = new ObjectID(
|
||||
req.params['projectId'] as string
|
||||
);
|
||||
|
||||
const token: string = JSONWebToken.sign(
|
||||
{
|
||||
userId: alreadySavedUser.id!,
|
||||
projectId: projectId,
|
||||
email: email,
|
||||
isMasterAdmin: false,
|
||||
},
|
||||
OneUptimeDate.getSecondsInDays(new PositiveNumber(30))
|
||||
);
|
||||
|
||||
// Refresh Permissions for this user here.
|
||||
await AccessTokenService.refreshUserAllPermissions(
|
||||
alreadySavedUser.id!
|
||||
);
|
||||
|
||||
const host: Hostname = await DatabaseConfig.getHost();
|
||||
const httpProtocol: Protocol =
|
||||
await DatabaseConfig.getHttpProtocol();
|
||||
|
||||
CookieUtil.setCookie(
|
||||
res,
|
||||
CookieUtil.getUserSSOKey(projectId),
|
||||
token,
|
||||
{
|
||||
maxAge: OneUptimeDate.getMillisecondsInDays(
|
||||
new PositiveNumber(30)
|
||||
),
|
||||
httpOnly: true,
|
||||
}
|
||||
);
|
||||
|
||||
return Response.redirect(
|
||||
if (!projectSSO) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new URL(
|
||||
httpProtocol,
|
||||
host,
|
||||
new Route(DashboardRoute.toString()).addRoute(
|
||||
'/' + req.params['projectId']
|
||||
),
|
||||
'sso_token=' + token
|
||||
)
|
||||
new BadRequestException('SSO Config not found')
|
||||
);
|
||||
} catch (err) {
|
||||
logger.error(err);
|
||||
Response.sendErrorResponse(req, res, new ServerException());
|
||||
}
|
||||
|
||||
// redirect to Identity Provider.
|
||||
|
||||
if (!projectSSO.issuerURL) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadRequestException('Issuer URL not found')
|
||||
);
|
||||
}
|
||||
|
||||
// redirect to Identity Provider.
|
||||
|
||||
if (!projectSSO.signOnURL) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadRequestException('Sign on URL not found')
|
||||
);
|
||||
}
|
||||
|
||||
if (!projectSSO.publicCertificate) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadRequestException('Public Certificate not found')
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
SSOUtil.isPayloadValid(response);
|
||||
|
||||
if (
|
||||
!SSOUtil.isSignatureValid(
|
||||
samlResponse,
|
||||
projectSSO.publicCertificate
|
||||
)
|
||||
) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadRequestException(
|
||||
'Signature is not valid or Public Certificate configured with this SSO provider is not valid'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
issuerUrl = SSOUtil.getIssuer(response);
|
||||
email = SSOUtil.getEmail(response);
|
||||
} catch (err: unknown) {
|
||||
if (err instanceof Exception) {
|
||||
return Response.sendErrorResponse(req, res, err);
|
||||
}
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new ServerException()
|
||||
);
|
||||
}
|
||||
|
||||
if (projectSSO.issuerURL.toString() !== issuerUrl) {
|
||||
logger.error("Issuer URL does not match. It should be "+projectSSO.issuerURL.toString()+" but it is "+issuerUrl.toString());
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadRequestException('Issuer URL does not match')
|
||||
);
|
||||
}
|
||||
|
||||
// Check if he already belongs to the project, If he does - then log in.
|
||||
|
||||
let alreadySavedUser: User | null = await UserService.findOneBy({
|
||||
query: { email: email },
|
||||
select: {
|
||||
_id: true,
|
||||
name: true,
|
||||
email: true,
|
||||
isMasterAdmin: true,
|
||||
isEmailVerified: true,
|
||||
profilePictureId: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
let isNewUser: boolean = false;
|
||||
|
||||
if (!alreadySavedUser) {
|
||||
// this should never happen because user is logged in before he signs in with SSO UNLESS he initiates the login though the IDP.
|
||||
|
||||
/// Create a user.
|
||||
|
||||
alreadySavedUser = await UserService.createByEmail(email, {
|
||||
isRoot: true,
|
||||
});
|
||||
|
||||
isNewUser = true;
|
||||
}
|
||||
|
||||
// If he does not then add him to teams that he should belong and log in.
|
||||
if (!alreadySavedUser.isEmailVerified && !isNewUser) {
|
||||
await AuthenticationEmail.sendVerificationEmail(
|
||||
alreadySavedUser!
|
||||
);
|
||||
|
||||
return Response.render(
|
||||
req,
|
||||
res,
|
||||
'/usr/src/app/FeatureSet/Identity/Views/Message.ejs',
|
||||
{
|
||||
title: 'Email not verified.',
|
||||
message:
|
||||
'Email is not verified. We have sent you an email with the verification link. Please do not forget to check spam.',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// check if the user already belongs to the project
|
||||
const teamMemberCount: PositiveNumber =
|
||||
await TeamMemberService.countBy({
|
||||
query: {
|
||||
projectId: new ObjectID(
|
||||
req.params['projectId'] as string
|
||||
),
|
||||
userId: alreadySavedUser!.id!,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (teamMemberCount.toNumber() === 0) {
|
||||
// user not in project, add him to default teams.
|
||||
|
||||
if (!projectSSO.teams || projectSSO.teams.length === 0) {
|
||||
return Response.render(
|
||||
req,
|
||||
res,
|
||||
'/usr/src/app/FeatureSet/Identity/Views/Message.ejs',
|
||||
{
|
||||
title: 'No teams added.',
|
||||
message:
|
||||
'No teams have been added to this SSO config. Please contact your admin and have default teams added.',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
for (const team of projectSSO.teams) {
|
||||
// add user to team
|
||||
let teamMember: TeamMember = new TeamMember();
|
||||
teamMember.projectId = new ObjectID(
|
||||
req.params['projectId'] as string
|
||||
);
|
||||
teamMember.userId = alreadySavedUser.id!;
|
||||
teamMember.hasAcceptedInvitation = true;
|
||||
teamMember.invitationAcceptedAt =
|
||||
OneUptimeDate.getCurrentDate();
|
||||
teamMember.teamId = team.id!;
|
||||
|
||||
teamMember = await TeamMemberService.create({
|
||||
data: teamMember,
|
||||
props: {
|
||||
isRoot: true,
|
||||
ignoreHooks: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (isNewUser) {
|
||||
return Response.render(
|
||||
req,
|
||||
res,
|
||||
'/usr/src/app/FeatureSet/Identity/Views/Message.ejs',
|
||||
{
|
||||
title: 'You have not signed up so far.',
|
||||
message:
|
||||
'You need to sign up for an account on OneUptime with this email:' +
|
||||
email.toString() +
|
||||
'. Once you have signed up, you can use SSO to log in to your project.',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const projectId: ObjectID = new ObjectID(
|
||||
req.params['projectId'] as string
|
||||
);
|
||||
|
||||
const token: string = JSONWebToken.sign(
|
||||
{
|
||||
userId: alreadySavedUser.id!,
|
||||
projectId: projectId,
|
||||
email: email,
|
||||
isMasterAdmin: false,
|
||||
},
|
||||
OneUptimeDate.getSecondsInDays(new PositiveNumber(30))
|
||||
);
|
||||
|
||||
// Refresh Permissions for this user here.
|
||||
await AccessTokenService.refreshUserAllPermissions(
|
||||
alreadySavedUser.id!
|
||||
);
|
||||
|
||||
const host: Hostname = await DatabaseConfig.getHost();
|
||||
const httpProtocol: Protocol =
|
||||
await DatabaseConfig.getHttpProtocol();
|
||||
|
||||
CookieUtil.setCookie(
|
||||
res,
|
||||
CookieUtil.getUserSSOKey(projectId),
|
||||
token,
|
||||
{
|
||||
maxAge: OneUptimeDate.getMillisecondsInDays(
|
||||
new PositiveNumber(30)
|
||||
),
|
||||
httpOnly: true,
|
||||
}
|
||||
);
|
||||
|
||||
return Response.redirect(
|
||||
req,
|
||||
res,
|
||||
new URL(
|
||||
httpProtocol,
|
||||
host,
|
||||
new Route(DashboardRoute.toString()).addRoute(
|
||||
'/' + req.params['projectId']
|
||||
),
|
||||
'sso_token=' + token
|
||||
)
|
||||
);
|
||||
} catch (err) {
|
||||
logger.error(err);
|
||||
Response.sendErrorResponse(req, res, new ServerException());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export default router;
|
||||
|
@ -18,11 +18,13 @@ export default class SSOUtil {
|
||||
payload =
|
||||
(payload['saml2p:Response'] as JSONObject) ||
|
||||
(payload['samlp:Response'] as JSONObject) ||
|
||||
(payload['samlp:Response'] as JSONObject);
|
||||
(payload['samlp:Response'] as JSONObject) ||
|
||||
(payload['Response'] as JSONObject);
|
||||
|
||||
const issuers: JSONArray =
|
||||
(payload['saml2:Issuer'] as JSONArray) ||
|
||||
(payload['saml:Issuer'] as JSONArray);
|
||||
(payload['saml:Issuer'] as JSONArray) ||
|
||||
(payload['Issuer'] as JSONArray);
|
||||
|
||||
if (issuers.length === 0) {
|
||||
throw new BadRequestException('Issuers not found');
|
||||
@ -47,7 +49,8 @@ export default class SSOUtil {
|
||||
|
||||
const samlAssertion: JSONArray =
|
||||
(payload['saml2:Assertion'] as JSONArray) ||
|
||||
(payload['saml:Assertion'] as JSONArray);
|
||||
(payload['saml:Assertion'] as JSONArray) ||
|
||||
(payload['Assertion'] as JSONArray);
|
||||
|
||||
if (!samlAssertion || samlAssertion.length === 0) {
|
||||
throw new BadRequestException('SAML Assertion not found');
|
||||
@ -55,7 +58,8 @@ export default class SSOUtil {
|
||||
|
||||
const samlSubject: JSONArray =
|
||||
((samlAssertion[0] as JSONObject)['saml2:Subject'] as JSONArray) ||
|
||||
((samlAssertion[0] as JSONObject)['saml:Subject'] as JSONArray);
|
||||
((samlAssertion[0] as JSONObject)['saml:Subject'] as JSONArray) ||
|
||||
((samlAssertion[0] as JSONObject)['Subject'] as JSONArray);
|
||||
|
||||
if (!samlSubject || samlSubject.length === 0) {
|
||||
throw new BadRequestException('SAML Subject not found');
|
||||
@ -63,7 +67,8 @@ export default class SSOUtil {
|
||||
|
||||
const samlNameId: JSONArray =
|
||||
((samlSubject[0] as JSONObject)['saml2:NameID'] as JSONArray) ||
|
||||
((samlSubject[0] as JSONObject)['saml:NameID'] as JSONArray);
|
||||
((samlSubject[0] as JSONObject)['saml:NameID'] as JSONArray) ||
|
||||
((samlSubject[0] as JSONObject)['NameID'] as JSONArray)
|
||||
|
||||
if (!samlNameId || samlNameId.length === 0) {
|
||||
throw new BadRequestException('SAML NAME ID not found');
|
||||
@ -120,11 +125,13 @@ export default class SSOUtil {
|
||||
|
||||
payload =
|
||||
(payload['saml2p:Response'] as JSONObject) ||
|
||||
(payload['samlp:Response'] as JSONObject);
|
||||
(payload['samlp:Response'] as JSONObject) ||
|
||||
(payload['Response'] as JSONObject)
|
||||
|
||||
const samlAssertion: JSONArray =
|
||||
(payload['saml2:Assertion'] as JSONArray) ||
|
||||
(payload['saml:Assertion'] as JSONArray);
|
||||
(payload['saml:Assertion'] as JSONArray) ||
|
||||
(payload['Assertion'] as JSONArray)
|
||||
|
||||
if (!samlAssertion || samlAssertion.length === 0) {
|
||||
throw new BadRequestException('SAML Assertion not found');
|
||||
@ -132,7 +139,8 @@ export default class SSOUtil {
|
||||
|
||||
const samlSubject: JSONArray =
|
||||
((samlAssertion[0] as JSONObject)['saml2:Subject'] as JSONArray) ||
|
||||
((samlAssertion[0] as JSONObject)['saml:Subject'] as JSONArray);
|
||||
((samlAssertion[0] as JSONObject)['saml:Subject'] as JSONArray) ||
|
||||
((samlAssertion[0] as JSONObject)['Subject'] as JSONArray)
|
||||
|
||||
if (!samlSubject || samlSubject.length === 0) {
|
||||
throw new BadRequestException('SAML Subject not found');
|
||||
@ -140,7 +148,8 @@ export default class SSOUtil {
|
||||
|
||||
const samlNameId: JSONArray =
|
||||
((samlSubject[0] as JSONObject)['saml2:NameID'] as JSONArray) ||
|
||||
((samlSubject[0] as JSONObject)['saml:NameID'] as JSONArray);
|
||||
((samlSubject[0] as JSONObject)['saml:NameID'] as JSONArray) ||
|
||||
((samlSubject[0] as JSONObject)['NameID'] as JSONArray);
|
||||
|
||||
if (!samlNameId || samlNameId.length === 0) {
|
||||
throw new BadRequestException('SAML NAME ID not found');
|
||||
@ -160,11 +169,13 @@ export default class SSOUtil {
|
||||
|
||||
payload =
|
||||
(payload['saml2p:Response'] as JSONObject) ||
|
||||
(payload['samlp:Response'] as JSONObject);
|
||||
(payload['samlp:Response'] as JSONObject) ||
|
||||
(payload['Response'] as JSONObject)
|
||||
|
||||
const issuers: JSONArray =
|
||||
(payload['saml2:Issuer'] as JSONArray) ||
|
||||
(payload['saml:Issuer'] as JSONArray);
|
||||
(payload['saml:Issuer'] as JSONArray) ||
|
||||
(payload['Issuer'] as JSONArray)
|
||||
|
||||
if (issuers.length === 0) {
|
||||
throw new BadRequestException('Issuers not found');
|
||||
|
4
App/package-lock.json
generated
4
App/package-lock.json
generated
@ -78,7 +78,7 @@
|
||||
"@opentelemetry/sdk-metrics": "^1.21.0",
|
||||
"@opentelemetry/sdk-node": "^0.48.0",
|
||||
"@opentelemetry/sdk-trace-node": "^1.21.0",
|
||||
"@socket.io/redis-adapter": "^8.2.1",
|
||||
"acme-client": "^5.3.0",
|
||||
"airtable": "^0.12.2",
|
||||
"bullmq": "^5.3.3",
|
||||
"Common": "file:../Common",
|
||||
@ -86,7 +86,7 @@
|
||||
"cors": "^2.8.5",
|
||||
"cron-parser": "^4.8.1",
|
||||
"dotenv": "^16.4.4",
|
||||
"ejs": "^3.1.8",
|
||||
"ejs": "^3.1.10",
|
||||
"express": "^4.19.2",
|
||||
"ioredis": "^5.3.2",
|
||||
"json2csv": "^5.0.7",
|
||||
|
51
CommonUI/package-lock.json
generated
51
CommonUI/package-lock.json
generated
@ -9,7 +9,7 @@
|
||||
"version": "1.0.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.24.0",
|
||||
"@babel/runtime": "^7.24.1",
|
||||
"@monaco-editor/react": "^4.4.6",
|
||||
"@nivo/core": "^0.85.1",
|
||||
"@nivo/line": "^0.85.1",
|
||||
@ -33,20 +33,20 @@
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^18.2.0",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
"react-big-calendar": "^1.11.1",
|
||||
"react-big-calendar": "^1.11.2",
|
||||
"react-color": "^2.19.3",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-dropzone": "^14.2.2",
|
||||
"react-error-boundary": "^4.0.13",
|
||||
"react-highlight": "^0.15.0",
|
||||
"react-markdown": "^8.0.3",
|
||||
"react-router-dom": "^6.22.2",
|
||||
"react-router-dom": "^6.22.3",
|
||||
"react-select": "^5.4.0",
|
||||
"react-spinners": "^0.13.6",
|
||||
"react-toggle": "^4.1.3",
|
||||
"reactflow": "^11.10.4",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"socket.io-client": "^4.7.4",
|
||||
"socket.io-client": "^4.7.5",
|
||||
"tippy.js": "^6.3.7",
|
||||
"universal-cookie": "^4.0.4",
|
||||
"use-async-effect": "^2.2.6"
|
||||
@ -78,13 +78,13 @@
|
||||
"dependencies": {
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"axios": "^1.6.7",
|
||||
"axios": "^1.6.8",
|
||||
"crypto-js": "^4.1.1",
|
||||
"json5": "^2.2.3",
|
||||
"moment": "^2.30.1",
|
||||
"moment-timezone": "^0.5.45",
|
||||
"posthog-js": "^1.112.0",
|
||||
"reflect-metadata": "^0.2.1",
|
||||
"posthog-js": "^1.116.6",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"slugify": "^1.6.5",
|
||||
"typeorm": "^0.3.20",
|
||||
"uuid": "^8.3.2"
|
||||
@ -9378,8 +9378,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.24.0",
|
||||
"license": "MIT",
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz",
|
||||
"integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==",
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.14.0"
|
||||
},
|
||||
@ -10583,8 +10584,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.15.2",
|
||||
"license": "MIT",
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz",
|
||||
"integrity": "sha512-Quz1KOffeEf/zwkCBM3kBtH4ZoZ+pT3xIXBG4PPW/XFtDP7EGhtTiC2+gpL9GnR7+Qdet5Oa6cYSvwKYg6kN9Q==",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
@ -15745,9 +15747,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-big-calendar": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/react-big-calendar/-/react-big-calendar-1.11.1.tgz",
|
||||
"integrity": "sha512-7GWxQjXo+ByJdouz8oJq51g1hhjCftmDqQmQYL5Loy2m0ibebF9hIGV5L/14ItRywSWQF9GpfCI7kJxPEISzjA==",
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/react-big-calendar/-/react-big-calendar-1.12.1.tgz",
|
||||
"integrity": "sha512-MCkuMHv/GrHbLo00eq2ixhiG9aHMD57NYnAQZgG3w2tqiHFwt29CB+hjfNTBdAQmR/F1bklgMILI8NogzbUEVA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.7",
|
||||
"clsx": "^1.2.1",
|
||||
@ -15926,10 +15928,11 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.22.2",
|
||||
"license": "MIT",
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.0.tgz",
|
||||
"integrity": "sha512-wPMZ8S2TuPadH0sF5irFGjkNLIcRvOSaEe7v+JER8508dyJumm6XZB1u5kztlX0RVq6AzRVndzqcUh6sFIauzA==",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.15.2"
|
||||
"@remix-run/router": "1.16.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@ -15939,11 +15942,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.22.2",
|
||||
"license": "MIT",
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.0.tgz",
|
||||
"integrity": "sha512-Q9YaSYvubwgbal2c9DJKfx6hTNoBp3iJDsl+Duva/DwxoJH+OTXkxGpql4iUK2sla/8z4RpjAm6EWx1qUDuopQ==",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.15.2",
|
||||
"react-router": "6.22.2"
|
||||
"@remix-run/router": "1.16.0",
|
||||
"react-router": "6.23.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@ -16347,8 +16351,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/socket.io-client": {
|
||||
"version": "4.7.4",
|
||||
"license": "MIT",
|
||||
"version": "4.7.5",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz",
|
||||
"integrity": "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==",
|
||||
"dependencies": {
|
||||
"@socket.io/component-emitter": "~3.1.0",
|
||||
"debug": "~4.3.2",
|
||||
|
38
Model/package-lock.json
generated
38
Model/package-lock.json
generated
@ -1,13 +1,13 @@
|
||||
{
|
||||
"name": "model",
|
||||
"name": "@oneuptime/model",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "model",
|
||||
"name": "@oneuptime/model",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"Common": "file:../Common",
|
||||
"typeorm": "^0.3.20"
|
||||
@ -20,21 +20,21 @@
|
||||
}
|
||||
},
|
||||
"../Common": {
|
||||
"name": "common",
|
||||
"name": "@oneuptime/common",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"axios": "^1.6.2",
|
||||
"axios": "^1.6.8",
|
||||
"crypto-js": "^4.1.1",
|
||||
"json5": "^2.2.3",
|
||||
"moment": "^2.29.2",
|
||||
"moment-timezone": "^0.5.40",
|
||||
"posthog-js": "^1.77.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"moment": "^2.30.1",
|
||||
"moment-timezone": "^0.5.45",
|
||||
"posthog-js": "^1.116.6",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"slugify": "^1.6.5",
|
||||
"typeorm": "^0.3.6",
|
||||
"typeorm": "^0.3.20",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -6063,21 +6063,21 @@
|
||||
"version": "file:../Common",
|
||||
"requires": {
|
||||
"@faker-js/faker": "^8.0.2",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/node": "^17.0.22",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"axios": "^1.6.2",
|
||||
"axios": "^1.6.8",
|
||||
"crypto-js": "^4.1.1",
|
||||
"jest": "^27.5.1",
|
||||
"json5": "^2.2.3",
|
||||
"moment": "^2.29.2",
|
||||
"moment-timezone": "^0.5.40",
|
||||
"posthog-js": "^1.77.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"moment": "^2.30.1",
|
||||
"moment-timezone": "^0.5.45",
|
||||
"posthog-js": "^1.116.6",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"slugify": "^1.6.5",
|
||||
"ts-jest": "^27.1.4",
|
||||
"typeorm": "^0.3.6",
|
||||
"typeorm": "^0.3.20",
|
||||
"uuid": "^8.3.2"
|
||||
}
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user