update deps

This commit is contained in:
Simon Larsen 2024-05-04 19:33:45 +01:00
parent 469e06280a
commit 9f76748037
No known key found for this signature in database
GPG Key ID: 96C5DCA24769DBCA
6 changed files with 407 additions and 375 deletions

View File

@ -35,19 +35,19 @@
} }
}, },
"../Common": { "../Common": {
"name": "common", "name": "@oneuptime/common",
"version": "1.0.0", "version": "1.0.0",
"license": "MIT", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@types/crypto-js": "^4.2.2", "@types/crypto-js": "^4.2.2",
"@types/uuid": "^8.3.4", "@types/uuid": "^8.3.4",
"axios": "^1.6.7", "axios": "^1.6.8",
"crypto-js": "^4.1.1", "crypto-js": "^4.1.1",
"json5": "^2.2.3", "json5": "^2.2.3",
"moment": "^2.30.1", "moment": "^2.30.1",
"moment-timezone": "^0.5.45", "moment-timezone": "^0.5.45",
"posthog-js": "^1.104.4", "posthog-js": "^1.116.6",
"reflect-metadata": "^0.2.1", "reflect-metadata": "^0.2.2",
"slugify": "^1.6.5", "slugify": "^1.6.5",
"typeorm": "^0.3.20", "typeorm": "^0.3.20",
"uuid": "^8.3.2" "uuid": "^8.3.2"
@ -61,49 +61,46 @@
} }
}, },
"../CommonServer": { "../CommonServer": {
"name": "common-server", "name": "@oneuptime/common-server",
"version": "1.0.0", "version": "1.0.0",
"license": "MIT", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@clickhouse/client": "^0.2.7", "@clickhouse/client": "^0.2.10",
"@elastic/elasticsearch": "^8.11.0", "@elastic/elasticsearch": "^8.12.1",
"@opentelemetry/api": "^1.7.0", "@opentelemetry/api": "^1.7.0",
"@opentelemetry/api-logs": "^0.48.0", "@opentelemetry/api-logs": "^0.49.1",
"@opentelemetry/exporter-logs-otlp-http": "^0.48.0", "@opentelemetry/auto-instrumentations-node": "^0.43.0",
"@opentelemetry/exporter-metrics-otlp-proto": "^0.48.0", "@opentelemetry/exporter-logs-otlp-http": "^0.49.1",
"@opentelemetry/exporter-trace-otlp-proto": "^0.48.0", "@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/id-generator-aws-xray": "^1.2.1",
"@opentelemetry/instrumentation-express": "^0.35.0", "@opentelemetry/sdk-logs": "^0.49.1",
"@opentelemetry/instrumentation-http": "^0.48.0",
"@opentelemetry/sdk-logs": "^0.48.0",
"@opentelemetry/sdk-metrics": "^1.21.0", "@opentelemetry/sdk-metrics": "^1.21.0",
"@opentelemetry/sdk-node": "^0.48.0", "@opentelemetry/sdk-node": "^0.48.0",
"@opentelemetry/sdk-trace-node": "^1.21.0", "@opentelemetry/sdk-trace-node": "^1.21.0",
"@socket.io/redis-adapter": "^8.2.1", "acme-client": "^5.3.0",
"airtable": "^0.12.2", "airtable": "^0.12.2",
"axios": "^1.6.4",
"bullmq": "^5.3.3", "bullmq": "^5.3.3",
"Common": "file:../Common", "Common": "file:../Common",
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",
"cors": "^2.8.5", "cors": "^2.8.5",
"cron-parser": "^4.8.1", "cron-parser": "^4.8.1",
"dotenv": "^16.4.1", "dotenv": "^16.4.4",
"ejs": "^3.1.8", "ejs": "^3.1.10",
"express": "^4.17.3", "express": "^4.19.2",
"ioredis": "^5.3.2", "ioredis": "^5.3.2",
"json2csv": "^5.0.7", "json2csv": "^5.0.7",
"jsonwebtoken": "^9.0.0", "jsonwebtoken": "^9.0.0",
"markdown-it": "^13.0.1", "markdown-it": "^13.0.1",
"Model": "file:../Model", "Model": "file:../Model",
"node-cron": "^3.0.3", "node-cron": "^3.0.3",
"nodemailer": "^6.9.9", "nodemailer": "^6.9.10",
"pg": "^8.7.3", "pg": "^8.7.3",
"socket.io": "^4.7.2", "socket.io": "^4.7.4",
"stripe": "^10.17.0", "stripe": "^10.17.0",
"twilio": "^4.19.3", "twilio": "^4.22.0",
"typeorm": "^0.3.20", "typeorm": "^0.3.20",
"typeorm-extension": "^2.2.13", "typeorm-extension": "^2.2.13"
"vm2": "^3.9.14"
}, },
"devDependencies": { "devDependencies": {
"@faker-js/faker": "^6.3.1", "@faker-js/faker": "^6.3.1",
@ -124,43 +121,48 @@
} }
}, },
"../CommonUI": { "../CommonUI": {
"name": "common-ui", "name": "@oneuptime/common-ui",
"version": "1.0.0", "version": "1.0.0",
"license": "MIT", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.24.1",
"@monaco-editor/react": "^4.4.6", "@monaco-editor/react": "^4.4.6",
"@opentelemetry/api": "^1.7.0", "@nivo/core": "^0.85.1",
"@opentelemetry/context-zone": "^1.21.0", "@nivo/line": "^0.85.1",
"@opentelemetry/exporter-trace-otlp-http": "^0.48.0", "@opentelemetry/api": "^1.8.0",
"@opentelemetry/instrumentation": "^0.48.0", "@opentelemetry/context-zone": "^1.22.0",
"@opentelemetry/instrumentation-fetch": "^0.48.0", "@opentelemetry/exporter-trace-otlp-http": "^0.49.1",
"@opentelemetry/instrumentation-xml-http-request": "^0.48.0", "@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/resources": "^1.21.0",
"@opentelemetry/sdk-trace-web": "^1.21.0", "@opentelemetry/sdk-trace-web": "^1.21.0",
"@opentelemetry/semantic-conventions": "^1.21.0", "@opentelemetry/semantic-conventions": "^1.21.0",
"@tippyjs/react": "^4.2.6", "@tippyjs/react": "^4.2.6",
"@types/react-highlight": "^0.12.8",
"Common": "file:../Common", "Common": "file:../Common",
"formik": "^2.2.9", "formik": "^2.2.9",
"history": "^5.3.0", "history": "^5.3.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"Model": "file:../Model", "Model": "file:../Model",
"moment-timezone": "^0.5.44", "moment-timezone": "^0.5.45",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"react": "^18.2.0", "react": "^18.2.0",
"react-beautiful-dnd": "^13.1.1", "react-beautiful-dnd": "^13.1.1",
"react-big-calendar": "^1.8.7", "react-big-calendar": "^1.11.2",
"react-color": "^2.19.3", "react-color": "^2.19.3",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",
"react-dropzone": "^14.2.2", "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-markdown": "^8.0.3",
"react-router-dom": "^6.21.3", "react-router-dom": "^6.22.3",
"react-select": "^5.4.0", "react-select": "^5.4.0",
"react-spinners": "^0.13.6", "react-spinners": "^0.13.6",
"react-toggle": "^4.1.3", "react-toggle": "^4.1.3",
"reactflow": "^11.10.3", "reactflow": "^11.10.4",
"remark-gfm": "^3.0.1", "remark-gfm": "^3.0.1",
"socket.io-client": "^4.7.4", "socket.io-client": "^4.7.5",
"tippy.js": "^6.3.7", "tippy.js": "^6.3.7",
"universal-cookie": "^4.0.4", "universal-cookie": "^4.0.4",
"use-async-effect": "^2.2.6" "use-async-effect": "^2.2.6"
@ -186,9 +188,9 @@
} }
}, },
"../Model": { "../Model": {
"name": "model", "name": "@oneuptime/model",
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"Common": "file:../Common", "Common": "file:../Common",
"typeorm": "^0.3.20" "typeorm": "^0.3.20"

View File

@ -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( router.post(
'/idp-login/:projectId/:projectSsoId', '/idp-login/:projectId/:projectSsoId',
async (req: ExpressRequest, res: ExpressResponse): Promise<void> => { async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {
try { return await loginUserWithSso(req, res);
const samlResponseBase64: string = req.body.SAMLResponse; }
);
const samlResponse: string = Buffer.from( const loginUserWithSso = async (req: ExpressRequest, res: ExpressResponse): Promise<void> => {
samlResponseBase64, try {
'base64'
).toString();
const response: JSONObject = await xml2js.parseStringPromise( debugger;
samlResponse 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 = ''; if (!req.params['projectSsoId']) {
let email: Email | null = null; return Response.sendErrorResponse(
req,
res,
new BadRequestException('Project SSO ID not found')
);
}
if (!req.params['projectId']) { const projectSSO: ProjectSSO | null =
return Response.sendErrorResponse( await ProjectSSOService.findOneBy({
req, query: {
res, projectId: new ObjectID(req.params['projectId']),
new BadRequestException('Project ID not found') _id: req.params['projectSsoId'],
); isEnabled: true,
} },
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 },
select: { select: {
_id: true, signOnURL: true,
name: true, issuerURL: true,
email: true, publicCertificate: true,
isMasterAdmin: true, teams: {
isEmailVerified: true, _id: true,
profilePictureId: true, },
}, },
props: { props: {
isRoot: true, isRoot: true,
}, },
}); });
let isNewUser: boolean = false; if (!projectSSO) {
return Response.sendErrorResponse(
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, req,
res, res,
new URL( new BadRequestException('SSO Config not found')
httpProtocol,
host,
new Route(DashboardRoute.toString()).addRoute(
'/' + req.params['projectId']
),
'sso_token=' + token
)
); );
} 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; export default router;

View File

@ -18,11 +18,13 @@ export default class SSOUtil {
payload = payload =
(payload['saml2p:Response'] as JSONObject) || (payload['saml2p:Response'] as JSONObject) ||
(payload['samlp: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 = const issuers: JSONArray =
(payload['saml2:Issuer'] as JSONArray) || (payload['saml2:Issuer'] as JSONArray) ||
(payload['saml:Issuer'] as JSONArray); (payload['saml:Issuer'] as JSONArray) ||
(payload['Issuer'] as JSONArray);
if (issuers.length === 0) { if (issuers.length === 0) {
throw new BadRequestException('Issuers not found'); throw new BadRequestException('Issuers not found');
@ -47,7 +49,8 @@ export default class SSOUtil {
const samlAssertion: JSONArray = const samlAssertion: JSONArray =
(payload['saml2:Assertion'] as 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) { if (!samlAssertion || samlAssertion.length === 0) {
throw new BadRequestException('SAML Assertion not found'); throw new BadRequestException('SAML Assertion not found');
@ -55,7 +58,8 @@ export default class SSOUtil {
const samlSubject: JSONArray = const samlSubject: JSONArray =
((samlAssertion[0] as JSONObject)['saml2:Subject'] as 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) { if (!samlSubject || samlSubject.length === 0) {
throw new BadRequestException('SAML Subject not found'); throw new BadRequestException('SAML Subject not found');
@ -63,7 +67,8 @@ export default class SSOUtil {
const samlNameId: JSONArray = const samlNameId: JSONArray =
((samlSubject[0] as JSONObject)['saml2:NameID'] as 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) { if (!samlNameId || samlNameId.length === 0) {
throw new BadRequestException('SAML NAME ID not found'); throw new BadRequestException('SAML NAME ID not found');
@ -120,11 +125,13 @@ export default class SSOUtil {
payload = payload =
(payload['saml2p:Response'] as JSONObject) || (payload['saml2p:Response'] as JSONObject) ||
(payload['samlp:Response'] as JSONObject); (payload['samlp:Response'] as JSONObject) ||
(payload['Response'] as JSONObject)
const samlAssertion: JSONArray = const samlAssertion: JSONArray =
(payload['saml2:Assertion'] as 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) { if (!samlAssertion || samlAssertion.length === 0) {
throw new BadRequestException('SAML Assertion not found'); throw new BadRequestException('SAML Assertion not found');
@ -132,7 +139,8 @@ export default class SSOUtil {
const samlSubject: JSONArray = const samlSubject: JSONArray =
((samlAssertion[0] as JSONObject)['saml2:Subject'] as 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) { if (!samlSubject || samlSubject.length === 0) {
throw new BadRequestException('SAML Subject not found'); throw new BadRequestException('SAML Subject not found');
@ -140,7 +148,8 @@ export default class SSOUtil {
const samlNameId: JSONArray = const samlNameId: JSONArray =
((samlSubject[0] as JSONObject)['saml2:NameID'] as 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) { if (!samlNameId || samlNameId.length === 0) {
throw new BadRequestException('SAML NAME ID not found'); throw new BadRequestException('SAML NAME ID not found');
@ -160,11 +169,13 @@ export default class SSOUtil {
payload = payload =
(payload['saml2p:Response'] as JSONObject) || (payload['saml2p:Response'] as JSONObject) ||
(payload['samlp:Response'] as JSONObject); (payload['samlp:Response'] as JSONObject) ||
(payload['Response'] as JSONObject)
const issuers: JSONArray = const issuers: JSONArray =
(payload['saml2:Issuer'] as JSONArray) || (payload['saml2:Issuer'] as JSONArray) ||
(payload['saml:Issuer'] as JSONArray); (payload['saml:Issuer'] as JSONArray) ||
(payload['Issuer'] as JSONArray)
if (issuers.length === 0) { if (issuers.length === 0) {
throw new BadRequestException('Issuers not found'); throw new BadRequestException('Issuers not found');

4
App/package-lock.json generated
View File

@ -78,7 +78,7 @@
"@opentelemetry/sdk-metrics": "^1.21.0", "@opentelemetry/sdk-metrics": "^1.21.0",
"@opentelemetry/sdk-node": "^0.48.0", "@opentelemetry/sdk-node": "^0.48.0",
"@opentelemetry/sdk-trace-node": "^1.21.0", "@opentelemetry/sdk-trace-node": "^1.21.0",
"@socket.io/redis-adapter": "^8.2.1", "acme-client": "^5.3.0",
"airtable": "^0.12.2", "airtable": "^0.12.2",
"bullmq": "^5.3.3", "bullmq": "^5.3.3",
"Common": "file:../Common", "Common": "file:../Common",
@ -86,7 +86,7 @@
"cors": "^2.8.5", "cors": "^2.8.5",
"cron-parser": "^4.8.1", "cron-parser": "^4.8.1",
"dotenv": "^16.4.4", "dotenv": "^16.4.4",
"ejs": "^3.1.8", "ejs": "^3.1.10",
"express": "^4.19.2", "express": "^4.19.2",
"ioredis": "^5.3.2", "ioredis": "^5.3.2",
"json2csv": "^5.0.7", "json2csv": "^5.0.7",

View File

@ -9,7 +9,7 @@
"version": "1.0.0", "version": "1.0.0",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.24.0", "@babel/runtime": "^7.24.1",
"@monaco-editor/react": "^4.4.6", "@monaco-editor/react": "^4.4.6",
"@nivo/core": "^0.85.1", "@nivo/core": "^0.85.1",
"@nivo/line": "^0.85.1", "@nivo/line": "^0.85.1",
@ -33,20 +33,20 @@
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"react": "^18.2.0", "react": "^18.2.0",
"react-beautiful-dnd": "^13.1.1", "react-beautiful-dnd": "^13.1.1",
"react-big-calendar": "^1.11.1", "react-big-calendar": "^1.11.2",
"react-color": "^2.19.3", "react-color": "^2.19.3",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",
"react-dropzone": "^14.2.2", "react-dropzone": "^14.2.2",
"react-error-boundary": "^4.0.13", "react-error-boundary": "^4.0.13",
"react-highlight": "^0.15.0", "react-highlight": "^0.15.0",
"react-markdown": "^8.0.3", "react-markdown": "^8.0.3",
"react-router-dom": "^6.22.2", "react-router-dom": "^6.22.3",
"react-select": "^5.4.0", "react-select": "^5.4.0",
"react-spinners": "^0.13.6", "react-spinners": "^0.13.6",
"react-toggle": "^4.1.3", "react-toggle": "^4.1.3",
"reactflow": "^11.10.4", "reactflow": "^11.10.4",
"remark-gfm": "^3.0.1", "remark-gfm": "^3.0.1",
"socket.io-client": "^4.7.4", "socket.io-client": "^4.7.5",
"tippy.js": "^6.3.7", "tippy.js": "^6.3.7",
"universal-cookie": "^4.0.4", "universal-cookie": "^4.0.4",
"use-async-effect": "^2.2.6" "use-async-effect": "^2.2.6"
@ -78,13 +78,13 @@
"dependencies": { "dependencies": {
"@types/crypto-js": "^4.2.2", "@types/crypto-js": "^4.2.2",
"@types/uuid": "^8.3.4", "@types/uuid": "^8.3.4",
"axios": "^1.6.7", "axios": "^1.6.8",
"crypto-js": "^4.1.1", "crypto-js": "^4.1.1",
"json5": "^2.2.3", "json5": "^2.2.3",
"moment": "^2.30.1", "moment": "^2.30.1",
"moment-timezone": "^0.5.45", "moment-timezone": "^0.5.45",
"posthog-js": "^1.112.0", "posthog-js": "^1.116.6",
"reflect-metadata": "^0.2.1", "reflect-metadata": "^0.2.2",
"slugify": "^1.6.5", "slugify": "^1.6.5",
"typeorm": "^0.3.20", "typeorm": "^0.3.20",
"uuid": "^8.3.2" "uuid": "^8.3.2"
@ -9378,8 +9378,9 @@
} }
}, },
"node_modules/@babel/runtime": { "node_modules/@babel/runtime": {
"version": "7.24.0", "version": "7.24.5",
"license": "MIT", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz",
"integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==",
"dependencies": { "dependencies": {
"regenerator-runtime": "^0.14.0" "regenerator-runtime": "^0.14.0"
}, },
@ -10583,8 +10584,9 @@
} }
}, },
"node_modules/@remix-run/router": { "node_modules/@remix-run/router": {
"version": "1.15.2", "version": "1.16.0",
"license": "MIT", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz",
"integrity": "sha512-Quz1KOffeEf/zwkCBM3kBtH4ZoZ+pT3xIXBG4PPW/XFtDP7EGhtTiC2+gpL9GnR7+Qdet5Oa6cYSvwKYg6kN9Q==",
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=14.0.0"
} }
@ -15745,9 +15747,9 @@
} }
}, },
"node_modules/react-big-calendar": { "node_modules/react-big-calendar": {
"version": "1.11.1", "version": "1.12.1",
"resolved": "https://registry.npmjs.org/react-big-calendar/-/react-big-calendar-1.11.1.tgz", "resolved": "https://registry.npmjs.org/react-big-calendar/-/react-big-calendar-1.12.1.tgz",
"integrity": "sha512-7GWxQjXo+ByJdouz8oJq51g1hhjCftmDqQmQYL5Loy2m0ibebF9hIGV5L/14ItRywSWQF9GpfCI7kJxPEISzjA==", "integrity": "sha512-MCkuMHv/GrHbLo00eq2ixhiG9aHMD57NYnAQZgG3w2tqiHFwt29CB+hjfNTBdAQmR/F1bklgMILI8NogzbUEVA==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.7", "@babel/runtime": "^7.20.7",
"clsx": "^1.2.1", "clsx": "^1.2.1",
@ -15926,10 +15928,11 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/react-router": { "node_modules/react-router": {
"version": "6.22.2", "version": "6.23.0",
"license": "MIT", "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.0.tgz",
"integrity": "sha512-wPMZ8S2TuPadH0sF5irFGjkNLIcRvOSaEe7v+JER8508dyJumm6XZB1u5kztlX0RVq6AzRVndzqcUh6sFIauzA==",
"dependencies": { "dependencies": {
"@remix-run/router": "1.15.2" "@remix-run/router": "1.16.0"
}, },
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=14.0.0"
@ -15939,11 +15942,12 @@
} }
}, },
"node_modules/react-router-dom": { "node_modules/react-router-dom": {
"version": "6.22.2", "version": "6.23.0",
"license": "MIT", "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.0.tgz",
"integrity": "sha512-Q9YaSYvubwgbal2c9DJKfx6hTNoBp3iJDsl+Duva/DwxoJH+OTXkxGpql4iUK2sla/8z4RpjAm6EWx1qUDuopQ==",
"dependencies": { "dependencies": {
"@remix-run/router": "1.15.2", "@remix-run/router": "1.16.0",
"react-router": "6.22.2" "react-router": "6.23.0"
}, },
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=14.0.0"
@ -16347,8 +16351,9 @@
} }
}, },
"node_modules/socket.io-client": { "node_modules/socket.io-client": {
"version": "4.7.4", "version": "4.7.5",
"license": "MIT", "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz",
"integrity": "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==",
"dependencies": { "dependencies": {
"@socket.io/component-emitter": "~3.1.0", "@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.2", "debug": "~4.3.2",

View File

@ -1,13 +1,13 @@
{ {
"name": "model", "name": "@oneuptime/model",
"version": "1.0.0", "version": "1.0.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "model", "name": "@oneuptime/model",
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"Common": "file:../Common", "Common": "file:../Common",
"typeorm": "^0.3.20" "typeorm": "^0.3.20"
@ -20,21 +20,21 @@
} }
}, },
"../Common": { "../Common": {
"name": "common", "name": "@oneuptime/common",
"version": "1.0.0", "version": "1.0.0",
"license": "MIT", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@types/crypto-js": "^4.1.1", "@types/crypto-js": "^4.2.2",
"@types/uuid": "^8.3.4", "@types/uuid": "^8.3.4",
"axios": "^1.6.2", "axios": "^1.6.8",
"crypto-js": "^4.1.1", "crypto-js": "^4.1.1",
"json5": "^2.2.3", "json5": "^2.2.3",
"moment": "^2.29.2", "moment": "^2.30.1",
"moment-timezone": "^0.5.40", "moment-timezone": "^0.5.45",
"posthog-js": "^1.77.0", "posthog-js": "^1.116.6",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.2.2",
"slugify": "^1.6.5", "slugify": "^1.6.5",
"typeorm": "^0.3.6", "typeorm": "^0.3.20",
"uuid": "^8.3.2" "uuid": "^8.3.2"
}, },
"devDependencies": { "devDependencies": {
@ -6063,21 +6063,21 @@
"version": "file:../Common", "version": "file:../Common",
"requires": { "requires": {
"@faker-js/faker": "^8.0.2", "@faker-js/faker": "^8.0.2",
"@types/crypto-js": "^4.1.1", "@types/crypto-js": "^4.2.2",
"@types/jest": "^27.5.2", "@types/jest": "^27.5.2",
"@types/node": "^17.0.22", "@types/node": "^17.0.22",
"@types/uuid": "^8.3.4", "@types/uuid": "^8.3.4",
"axios": "^1.6.2", "axios": "^1.6.8",
"crypto-js": "^4.1.1", "crypto-js": "^4.1.1",
"jest": "^27.5.1", "jest": "^27.5.1",
"json5": "^2.2.3", "json5": "^2.2.3",
"moment": "^2.29.2", "moment": "^2.30.1",
"moment-timezone": "^0.5.40", "moment-timezone": "^0.5.45",
"posthog-js": "^1.77.0", "posthog-js": "^1.116.6",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.2.2",
"slugify": "^1.6.5", "slugify": "^1.6.5",
"ts-jest": "^27.1.4", "ts-jest": "^27.1.4",
"typeorm": "^0.3.6", "typeorm": "^0.3.20",
"uuid": "^8.3.2" "uuid": "^8.3.2"
} }
}, },