Applied prettier
This commit is contained in:
parent
4f361d4a11
commit
cb8b857008
@ -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 (
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
|
|
||||||
export async function handler(req: NextApiRequest, res: NextApiResponse) {
|
export async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
if (req.method === "POST") {
|
if (req.method === 'POST') {
|
||||||
res.status(200).json({ name: "John Doe" });
|
res.status(200).json({ name: 'John Doe' });
|
||||||
} else {
|
} else {
|
||||||
res.status(405).send(`Method ${req.method} Not Allowed`);
|
res.status(405).send(`Method ${req.method} Not Allowed`);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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,
|
|
||||||
}
|
|
||||||
|
|||||||
@ -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,
|
|
||||||
}
|
|
||||||
|
|||||||
@ -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]['_'],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -5,12 +5,12 @@ import { SignedXml, FileKeyInfo } from 'xml-crypto';
|
|||||||
import { pki, util, asn1 } from 'node-forge';
|
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;
|
||||||
|
|
||||||
const authDate = new Date();
|
const authDate = new Date();
|
||||||
const authTimestamp = authDate.toISOString();
|
const authTimestamp = authDate.toISOString();
|
||||||
@ -21,46 +21,46 @@ 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 = {
|
||||||
'@xmlns:xs': 'http://www.w3.org/2001/XMLSchema',
|
'@xmlns:xs': 'http://www.w3.org/2001/XMLSchema',
|
||||||
'@xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
|
'@xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
|
||||||
'saml:Attribute' : [
|
'saml:Attribute': [
|
||||||
{
|
{
|
||||||
'@Name': 'id',
|
'@Name': 'id',
|
||||||
'@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': {
|
||||||
'@xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol',
|
'@xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol',
|
||||||
'@Version': '2.0',
|
'@Version': '2.0',
|
||||||
'@ID': responseId,
|
'@ID': responseId,
|
||||||
@ -69,8 +69,8 @@ const createResponseXML = async (params: {
|
|||||||
'@IssueInstant': authTimestamp,
|
'@IssueInstant': authTimestamp,
|
||||||
'samlp:Status': {
|
'samlp:Status': {
|
||||||
'samlp:StatusCode': {
|
'samlp:StatusCode': {
|
||||||
'@Value': 'urn:oasis:names:tc:SAML:2.0:status:Success'
|
'@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',
|
||||||
@ -88,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,
|
||||||
@ -96,24 +96,24 @@ 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 });
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the HTML form to submit the response
|
// Create the HTML form to submit the response
|
||||||
@ -171,8 +171,10 @@ function GetKeyInfo(x509Certificate: string, signatureConfig: any = {}) {
|
|||||||
|
|
||||||
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 =
|
||||||
|
'/*[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';
|
||||||
|
|
||||||
@ -180,17 +182,17 @@ const signResponseXML = async (xml: string, signingKey: any, publicKey: any): Pr
|
|||||||
sig.keyInfoProvider = new GetKeyInfo(publicKey, {});
|
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
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user