Merge branch 'main' of github.com:boxyhq/mock-saml

This commit is contained in:
Aswin V 2022-02-22 13:51:31 +05:30
commit 3fee129623
11 changed files with 133 additions and 263 deletions

View File

@ -2,8 +2,10 @@ const appUrl = process.env.APP_URL || 'http://localhost:4000';
const entityId = process.env.ENTITY_ID || 'http://saml.example.com'; const entityId = process.env.ENTITY_ID || 'http://saml.example.com';
const ssoUrl = `${appUrl}/api/saml/sso`; const ssoUrl = `${appUrl}/api/saml/sso`;
export default { const config = {
appUrl, appUrl,
entityId, entityId,
ssoUrl, ssoUrl,
}; };
export default config;

204
package-lock.json generated
View File

@ -6,10 +6,8 @@
"": { "": {
"name": "fake", "name": "fake",
"dependencies": { "dependencies": {
"axios": "^0.24.0",
"next": "12.1.0", "next": "12.1.0",
"node-fetch": "^3.2.0", "node-forge": "^1.2.1",
"rambda": "^7.0.2",
"react": "17.0.2", "react": "17.0.2",
"react-dom": "17.0.2", "react-dom": "17.0.2",
"webpack-filter-warnings-plugin": "^1.2.1", "webpack-filter-warnings-plugin": "^1.2.1",
@ -19,6 +17,7 @@
}, },
"devDependencies": { "devDependencies": {
"@types/node": "17.0.8", "@types/node": "17.0.8",
"@types/node-forge": "^1.0.0",
"@types/react": "17.0.38", "@types/react": "17.0.38",
"@types/xml-crypto": "^1.4.2", "@types/xml-crypto": "^1.4.2",
"@types/xml2js": "0.4.9", "@types/xml2js": "0.4.9",
@ -432,6 +431,15 @@
"integrity": "sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg==", "integrity": "sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg==",
"dev": true "dev": true
}, },
"node_modules/@types/node-forge": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.0.0.tgz",
"integrity": "sha512-h0bgwPKq5u99T9Gor4qtV1lCZ41xNkai0pie1n/a2mh2/4+jENWOlo7AJ4YKxTZAnSZ8FRurUpdIN7ohaPPuHA==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/parse-json": { "node_modules/@types/parse-json": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
@ -1222,14 +1230,6 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/axios": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
"integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
"dependencies": {
"follow-redirects": "^1.14.4"
}
},
"node_modules/axobject-query": { "node_modules/axobject-query": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
@ -2008,14 +2008,6 @@
"integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
"dev": true "dev": true
}, },
"node_modules/data-uri-to-buffer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
"integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==",
"engines": {
"node": ">= 12"
}
},
"node_modules/debug": { "node_modules/debug": {
"version": "2.6.9", "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@ -3310,28 +3302,6 @@
"reusify": "^1.0.4" "reusify": "^1.0.4"
} }
}, },
"node_modules/fetch-blob": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.4.tgz",
"integrity": "sha512-Eq5Xv5+VlSrYWEqKrusxY1C3Hm/hjeAsCGVG3ft7pZahlUAChpGZT/Ms1WmSLnEAisEXszjzu/s+ce6HZB2VHA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "paypal",
"url": "https://paypal.me/jimmywarting"
}
],
"dependencies": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
},
"engines": {
"node": "^12.20 || >= 14.13"
}
},
"node_modules/figgy-pudding": { "node_modules/figgy-pudding": {
"version": "3.5.2", "version": "3.5.2",
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
@ -3428,25 +3398,6 @@
"safe-buffer": "~5.1.0" "safe-buffer": "~5.1.0"
} }
}, },
"node_modules/follow-redirects": {
"version": "1.14.7",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
"integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/for-in": { "node_modules/for-in": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@ -3456,17 +3407,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"dependencies": {
"fetch-blob": "^3.1.2"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/fraction.js": { "node_modules/fraction.js": {
"version": "4.1.2", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.2.tgz", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.2.tgz",
@ -4785,39 +4725,12 @@
"url": "https://opencollective.com/postcss/" "url": "https://opencollective.com/postcss/"
} }
}, },
"node_modules/node-domexception": { "node_modules/node-forge": {
"version": "1.0.0", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.2.1.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", "integrity": "sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"engines": { "engines": {
"node": ">=10.5.0" "node": ">= 6.13.0"
}
},
"node_modules/node-fetch": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.0.tgz",
"integrity": "sha512-8xeimMwMItMw8hRrOl3C9/xzU49HV/yE6ORew/l+dxWimO5A4Ra8ld2rerlJvc/O7et5Z1zrWsPX43v1QBjCxw==",
"dependencies": {
"data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/node-fetch"
} }
}, },
"node_modules/node-libs-browser": { "node_modules/node-libs-browser": {
@ -5725,11 +5638,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/rambda": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/rambda/-/rambda-7.0.2.tgz",
"integrity": "sha512-oM1In0rXyFIzhYDIwREhdOm+oTDwtGW5WIgo/m8TqzS5kSBvsu8UoqzQFrSA0SJCdWJQCqOsvK0pKEINTwcEIA=="
},
"node_modules/randombytes": { "node_modules/randombytes": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@ -7644,14 +7552,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/web-streams-polyfill": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz",
"integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==",
"engines": {
"node": ">= 8"
}
},
"node_modules/webpack": { "node_modules/webpack": {
"version": "4.46.0", "version": "4.46.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz",
@ -8294,6 +8194,15 @@
"integrity": "sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg==", "integrity": "sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg==",
"dev": true "dev": true
}, },
"@types/node-forge": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.0.0.tgz",
"integrity": "sha512-h0bgwPKq5u99T9Gor4qtV1lCZ41xNkai0pie1n/a2mh2/4+jENWOlo7AJ4YKxTZAnSZ8FRurUpdIN7ohaPPuHA==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/parse-json": { "@types/parse-json": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
@ -8912,14 +8821,6 @@
"integrity": "sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA==", "integrity": "sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA==",
"dev": true "dev": true
}, },
"axios": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
"integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
"requires": {
"follow-redirects": "^1.14.4"
}
},
"axobject-query": { "axobject-query": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
@ -9593,11 +9494,6 @@
"integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
"dev": true "dev": true
}, },
"data-uri-to-buffer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
"integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA=="
},
"debug": { "debug": {
"version": "2.6.9", "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@ -10636,15 +10532,6 @@
"reusify": "^1.0.4" "reusify": "^1.0.4"
} }
}, },
"fetch-blob": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.4.tgz",
"integrity": "sha512-Eq5Xv5+VlSrYWEqKrusxY1C3Hm/hjeAsCGVG3ft7pZahlUAChpGZT/Ms1WmSLnEAisEXszjzu/s+ce6HZB2VHA==",
"requires": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
}
},
"figgy-pudding": { "figgy-pudding": {
"version": "3.5.2", "version": "3.5.2",
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
@ -10734,25 +10621,12 @@
} }
} }
}, },
"follow-redirects": {
"version": "1.14.7",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
"integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ=="
},
"for-in": { "for-in": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
"integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
"peer": true "peer": true
}, },
"formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"requires": {
"fetch-blob": "^3.1.2"
}
},
"fraction.js": { "fraction.js": {
"version": "4.1.2", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.2.tgz", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.2.tgz",
@ -11778,20 +11652,10 @@
} }
} }
}, },
"node-domexception": { "node-forge": {
"version": "1.0.0", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.2.1.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" "integrity": "sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w=="
},
"node-fetch": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.0.tgz",
"integrity": "sha512-8xeimMwMItMw8hRrOl3C9/xzU49HV/yE6ORew/l+dxWimO5A4Ra8ld2rerlJvc/O7et5Z1zrWsPX43v1QBjCxw==",
"requires": {
"data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
}
}, },
"node-libs-browser": { "node-libs-browser": {
"version": "2.2.1", "version": "2.2.1",
@ -12515,11 +12379,6 @@
"integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
"dev": true "dev": true
}, },
"rambda": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/rambda/-/rambda-7.0.2.tgz",
"integrity": "sha512-oM1In0rXyFIzhYDIwREhdOm+oTDwtGW5WIgo/m8TqzS5kSBvsu8UoqzQFrSA0SJCdWJQCqOsvK0pKEINTwcEIA=="
},
"randombytes": { "randombytes": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@ -14044,11 +13903,6 @@
} }
} }
}, },
"web-streams-polyfill": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz",
"integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA=="
},
"webpack": { "webpack": {
"version": "4.46.0", "version": "4.46.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz",

View File

@ -8,10 +8,8 @@
"lint": "next lint" "lint": "next lint"
}, },
"dependencies": { "dependencies": {
"axios": "^0.24.0",
"next": "12.1.0", "next": "12.1.0",
"node-fetch": "^3.2.0", "node-forge": "^1.2.1",
"rambda": "^7.0.2",
"react": "17.0.2", "react": "17.0.2",
"react-dom": "17.0.2", "react-dom": "17.0.2",
"webpack-filter-warnings-plugin": "^1.2.1", "webpack-filter-warnings-plugin": "^1.2.1",
@ -21,14 +19,15 @@
}, },
"devDependencies": { "devDependencies": {
"@types/node": "17.0.8", "@types/node": "17.0.8",
"@types/node-forge": "^1.0.0",
"@types/react": "17.0.38", "@types/react": "17.0.38",
"@types/xml-crypto": "^1.4.2",
"@types/xml2js": "0.4.9", "@types/xml2js": "0.4.9",
"autoprefixer": "10.4.2", "autoprefixer": "10.4.2",
"eslint": "8.6.0", "eslint": "8.6.0",
"eslint-config-next": "12.0.7", "eslint-config-next": "12.0.7",
"postcss": "8.4.6", "postcss": "8.4.6",
"tailwindcss": "3.0.23", "tailwindcss": "3.0.23",
"typescript": "4.5.4", "typescript": "4.5.4"
"@types/xml-crypto": "^1.4.2"
} }
} }

View File

@ -1,6 +1,6 @@
import "styles/globals.css"; import 'styles/globals.css';
import type { AppProps } from "next/app"; import type { AppProps } from 'next/app';
import Layout from "components/Layout"; import Layout from 'components/Layout';
function MyApp({ Component, pageProps }: AppProps) { function MyApp({ Component, pageProps }: AppProps) {
return ( return (

View File

@ -1,22 +1,18 @@
import Document, { Html, Head, Main, NextScript } from "next/document"; import Document, { Html, Head, Main, NextScript } from 'next/document';
class MyDocument extends Document { class MyDocument extends Document {
render() { render() {
return ( return (
<Html> <Html>
<Head> <Head>
<link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel='preconnect' href='https://fonts.googleapis.com' />
<link rel='preconnect' href='https://fonts.gstatic.com' crossOrigin='true' />
<link <link
rel="preconnect" href='https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;700;800&display=swap'
href="https://fonts.gstatic.com" rel='stylesheet'
crossOrigin="true"
/>
<link
href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;700;800&display=swap"
rel="stylesheet"
/> />
</Head> </Head>
<body className="theme-default"> <body className='theme-default'>
<Main /> <Main />
<NextScript /> <NextScript />
</body> </body>

View File

@ -1,13 +1,10 @@
import type { GetServerSideProps } from 'next'; import type { GetServerSideProps } from 'next';
import React from "react"; import React from 'react';
import { AuthNRequest } from '../../types' import { AuthNRequest } from '../../types';
import { extractSAMLRequestAttributes, createResponseForm } from '../../utils' import { extractSAMLRequestAttributes, createResponseForm } from '../../utils';
const ProcessRequest: React.FC<AuthNRequest> = ({ relayState, samlRequest }) => { const ProcessRequest: React.FC<AuthNRequest> = ({ relayState, samlRequest }) => {
return ( return <div>Processing request</div>;
<div>Processing request</div> };
);
}
export default ProcessRequest; export default ProcessRequest;

View File

@ -7,7 +7,7 @@ const fetchPublicKey = async (): Promise<string> => {
const fetchPrivateKey = async (): Promise<string> => { const fetchPrivateKey = async (): Promise<string> => {
return await fs.readFile(path.join('data', 'key.pem'), 'ascii'); return await fs.readFile(path.join('data', 'key.pem'), 'ascii');
} };
const stripCertHeaderAndFooter = (cert: string): string => { const stripCertHeaderAndFooter = (cert: string): string => {
cert = cert.replace(/-+BEGIN CERTIFICATE-+\r?\n?/, ''); cert = cert.replace(/-+BEGIN CERTIFICATE-+\r?\n?/, '');
@ -17,8 +17,4 @@ const stripCertHeaderAndFooter = (cert: string): string => {
return cert; return cert;
}; };
export { export { fetchPublicKey, fetchPrivateKey, stripCertHeaderAndFooter };
fetchPublicKey,
fetchPrivateKey,
stripCertHeaderAndFooter,
}

View File

@ -13,7 +13,7 @@ const createIdPMetadataXML = async ({
}): Promise<string> => { }): Promise<string> => {
const xmlPath = path.join('data', 'idp-metadata.xml'); const xmlPath = path.join('data', 'idp-metadata.xml');
const xml = await fs.readFile(xmlPath, 'utf8'); const xml = await fs.readFile(xmlPath, 'utf8');
certificate = stripCertHeaderAndFooter(certificate) certificate = stripCertHeaderAndFooter(certificate);
return xml return xml
.replace('idp_entity_id', idpEntityId) .replace('idp_entity_id', idpEntityId)
@ -21,6 +21,4 @@ const createIdPMetadataXML = async ({
.replace(/idp_sso_url/g, idpSsoUrl); .replace(/idp_sso_url/g, idpSsoUrl);
}; };
export { export { createIdPMetadataXML };
createIdPMetadataXML,
}

View File

@ -1,6 +1,6 @@
import xml2js from "xml2js"; import xml2js from 'xml2js';
import { promisify } from "util"; import { promisify } from 'util';
import { inflateRaw } from "zlib"; import { inflateRaw } from 'zlib';
const inflateRawAsync = promisify(inflateRaw); const inflateRawAsync = promisify(inflateRaw);
@ -19,18 +19,16 @@ const parseXML = (xml: string): Promise<Record<string, any>> => {
// Parse SAMLRequest attributes // Parse SAMLRequest attributes
const extractSAMLRequestAttributes = async (samlRequest: string) => { const extractSAMLRequestAttributes = async (samlRequest: string) => {
const request = ( const request = (await inflateRawAsync(Buffer.from(samlRequest, 'base64'))).toString();
await inflateRawAsync(Buffer.from(samlRequest, "base64"))
).toString();
const result = await parseXML(request); const result = await parseXML(request);
const attributes = result["samlp:AuthnRequest"]["$"]; const attributes = result['samlp:AuthnRequest']['$'];
const issuer = result["samlp:AuthnRequest"]["saml:Issuer"]; const issuer = result['samlp:AuthnRequest']['saml:Issuer'];
return { return {
id: attributes.ID, id: attributes.ID,
acsUrl: attributes.AssertionConsumerServiceURL, acsUrl: attributes.AssertionConsumerServiceURL,
providerName: attributes.ProviderName, providerName: attributes.ProviderName,
audience: issuer[0]["_"], audience: issuer[0]['_'],
}; };
}; };

View File

@ -2,12 +2,13 @@ import { User } from '../types';
import xmlbuilder from 'xmlbuilder'; import xmlbuilder from 'xmlbuilder';
import crypto from 'crypto'; import crypto from 'crypto';
import { SignedXml, FileKeyInfo } from 'xml-crypto'; import { SignedXml, FileKeyInfo } from 'xml-crypto';
import { pki, util, asn1 } from 'node-forge';
const createResponseXML = async (params: { const createResponseXML = async (params: {
idpIdentityId: string, idpIdentityId: string;
audience: string, audience: string;
acsUrl: string, acsUrl: string;
user: User user: User;
}): Promise<string> => { }): Promise<string> => {
const { idpIdentityId, audience, acsUrl, user } = params; const { idpIdentityId, audience, acsUrl, user } = params;
@ -20,7 +21,7 @@ const createResponseXML = async (params: {
authDate.setMinutes(authDate.getMinutes() + 10); authDate.setMinutes(authDate.getMinutes() + 10);
const notAfter = authDate.toISOString(); const notAfter = authDate.toISOString();
const inResponseTo = '_1234' const inResponseTo = '_1234';
const responseId = crypto.randomBytes(10).toString('hex'); const responseId = crypto.randomBytes(10).toString('hex');
const attributeStatement = { const attributeStatement = {
@ -32,31 +33,31 @@ const createResponseXML = async (params: {
'@NameFormat': 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', '@NameFormat': 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic',
'saml:AttributeValue': { 'saml:AttributeValue': {
'#text': user.id, '#text': user.id,
} },
}, },
{ {
'@Name': 'email', '@Name': 'email',
'@NameFormat': 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', '@NameFormat': 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic',
'saml:AttributeValue': { 'saml:AttributeValue': {
'#text': user.email, '#text': user.email,
} },
}, },
{ {
'@Name': 'firstName', '@Name': 'firstName',
'@NameFormat': 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', '@NameFormat': 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic',
'saml:AttributeValue': { 'saml:AttributeValue': {
'#text': user.firstName, '#text': user.firstName,
} },
}, },
{ {
'@Name': 'lastName', '@Name': 'lastName',
'@NameFormat': 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic', '@NameFormat': 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic',
'saml:AttributeValue': { 'saml:AttributeValue': {
'#text': user.lastName, '#text': user.lastName,
}
}, },
] },
} ],
};
const nodes = { const nodes = {
'samlp:Response': { 'samlp:Response': {
@ -66,15 +67,15 @@ const createResponseXML = async (params: {
'@Destination': acsUrl, '@Destination': acsUrl,
'@InResponseTo': inResponseTo, '@InResponseTo': inResponseTo,
'@IssueInstant': authTimestamp, '@IssueInstant': authTimestamp,
'samlp:Status': {
'samlp:StatusCode': {
'@Value': 'urn:oasis:names:tc:SAML:2.0:status:Success',
},
},
'saml:Issuer': { 'saml:Issuer': {
'@xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion', '@xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion',
'#text': idpIdentityId, '#text': idpIdentityId,
}, },
'samlp:Status': {
'samlp:StatusCode': {
'@Value': 'urn:oasis:names:tc:SAML:2.0:status:Success'
}
},
'saml:Assertion': { 'saml:Assertion': {
'@xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion', '@xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion',
'@Version': '2.0', '@Version': '2.0',
@ -87,7 +88,7 @@ const createResponseXML = async (params: {
'saml:NameID': { 'saml:NameID': {
'@Format': 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified', '@Format': 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',
'#text': user.email, '#text': user.email,
} },
}, },
'saml:Conditions': { 'saml:Conditions': {
'@NotBefore': notBefore, '@NotBefore': notBefore,
@ -95,22 +96,22 @@ const createResponseXML = async (params: {
'saml:AudienceRestriction': { 'saml:AudienceRestriction': {
'saml:Audience': { 'saml:Audience': {
'#text': audience, '#text': audience,
} },
} },
}, },
'saml:AuthnStatement': { 'saml:AuthnStatement': {
'@AuthnInstant': authTimestamp, '@AuthnInstant': authTimestamp,
'@SessionIndex': '_YIlFoNFzLMDYxdwf-T_BuimfkGa5qhKg', '@SessionIndex': '_YIlFoNFzLMDYxdwf-T_BuimfkGa5qhKg',
'saml:AuthnContext': { 'saml:AuthnContext': {
'saml:AuthnContextClassRef': { 'saml:AuthnContextClassRef': {
'#text': 'urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified' '#text': 'urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified',
} },
} },
}, },
'saml:AttributeStatement': attributeStatement, 'saml:AttributeStatement': attributeStatement,
}, },
} },
} };
return xmlbuilder.create(nodes).end({ pretty: true }); return xmlbuilder.create(nodes).end({ pretty: true });
}; };
@ -141,28 +142,57 @@ const createResponseForm = (relayState: string, encodedSamlResponse: string, acs
return formElements.join(''); return formElements.join('');
}; };
function getPublicKeyPemFromCertificate(x509Certificate: string) {
const certDerBytes = util.decode64(x509Certificate);
const obj = asn1.fromDer(certDerBytes);
const cert = pki.certificateFromAsn1(obj);
return pki.publicKeyToPem(cert.publicKey);
}
const stripCertHeaderAndFooter = (cert: string): string => {
cert = cert.replace(/-+BEGIN CERTIFICATE-+\r?\n?/, '');
cert = cert.replace(/-+END CERTIFICATE-+\r?\n?/, '');
cert = cert.replace(/\r\n/g, '\n');
return cert;
};
function GetKeyInfo(x509Certificate: string, signatureConfig: any = {}) {
x509Certificate = stripCertHeaderAndFooter(x509Certificate);
this.getKeyInfo = () => {
const prefix = signatureConfig.prefix ? `${signatureConfig.prefix}:` : '';
return `<${prefix}X509Data><${prefix}X509Certificate>${x509Certificate}</${prefix}X509Certificate></${prefix}X509Data>`;
};
this.getKey = () => {
return getPublicKeyPemFromCertificate(x509Certificate).toString();
};
}
const signResponseXML = async (xml: string, signingKey: any, publicKey: any): Promise<string> => { const signResponseXML = async (xml: string, signingKey: any, publicKey: any): Promise<string> => {
const sig = new SignedXml(); const sig = new SignedXml();
const responseXPath = '/*[local-name(.)="Response" and namespace-uri(.)="urn:oasis:names:tc:SAML:2.0:protocol"]'; const responseXPath =
const issuerXPath = '/*[local-name(.)="Issuer" and namespace-uri(.)="urn:oasis:names:tc:SAML:2.0:assertion"]'; '/*[local-name(.)="Response" and namespace-uri(.)="urn:oasis:names:tc:SAML:2.0:protocol"]';
const issuerXPath =
console.log({publicKey, signingKey}) '/*[local-name(.)="Issuer" and namespace-uri(.)="urn:oasis:names:tc:SAML:2.0:assertion"]';
sig.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'; sig.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
sig.keyInfoProvider = new FileKeyInfo(publicKey);
// @ts-ignore
sig.keyInfoProvider = new GetKeyInfo(publicKey, {});
sig.signingKey = signingKey; sig.signingKey = signingKey;
sig.addReference(responseXPath, ['http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#'], 'http://www.w3.org/2001/04/xmlenc#sha256'); sig.addReference(
responseXPath,
['http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#'],
'http://www.w3.org/2001/04/xmlenc#sha256'
);
sig.computeSignature(xml, { sig.computeSignature(xml, {
location: { reference: responseXPath + issuerXPath, action: 'after' }, location: { reference: responseXPath + issuerXPath, action: 'after' },
}); });
return sig.getSignedXml(); return sig.getSignedXml();
} };
export { export { createResponseXML, createResponseForm, signResponseXML };
createResponseXML,
createResponseForm,
signResponseXML
}