diff --git a/cert_chain.crt b/cert_chain.crt new file mode 100644 index 00000000..99ea13e0 --- /dev/null +++ b/cert_chain.crt @@ -0,0 +1,98 @@ +-----BEGIN CERTIFICATE----- +MIIFYzCCBEugAwIBAgIQA6rbgXGYPzeo4y0pZyTW3zANBgkqhkiG9w0BAQsFADCB +kDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxNjA0BgNV +BAMTLUNPTU9ETyBSU0EgRG9tYWluIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZlciBD +QTAeFw0xNjA5MDUwMDAwMDBaFw0xNzA5MDMyMzU5NTlaMFkxITAfBgNVBAsTGERv +bWFpbiBDb250cm9sIFZhbGlkYXRlZDEUMBIGA1UECxMLUG9zaXRpdmVTU0wxHjAc +BgNVBAMTFWFscGhhLmVkaXRvci5wNWpzLm9yZzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAKfMrXVqIeItu+uQKdUcx5ytGWwdIpFpYVsoS5Y2ewqf7r+q +v+npJGdp37ebOJ4itV3RArU/erUAaPDAFs7S+37HtDALAwcCdg5/ZSGh52QLsLQu +p+aW3eVgidmFtaQj2NuDud5uaHw/weTe4c9UPxtzt6sg65iPcjtnSmRnoqvNrYGi +qYdgZ+ggBiEtyyyHWb++okRmzkkaC3I3+YtEElSPNMKoPximzbVdGoUu4BsIHBnk +u/gY6xinmeg+SOo/BpM59/pKsVPKBk+DAtm+OK/pi2scsrnd3cv+Cfzzku/2sBlu +yuDndSKzfqvZnLQ8oN7ZwGXK9yz1x6k+DXbkaBcCAwEAAaOCAe0wggHpMB8GA1Ud +IwQYMBaAFJCvajqUWgvYkOoSVnPfQ7Q6KNrnMB0GA1UdDgQWBBTG0d+Z1yL2Dadi +HS9X011EYC9RTzAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHSUE +FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwTwYDVR0gBEgwRjA6BgsrBgEEAbIxAQIC +BzArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5jb21vZG8uY29tL0NQUzAI +BgZngQwBAgEwVAYDVR0fBE0wSzBJoEegRYZDaHR0cDovL2NybC5jb21vZG9jYS5j +b20vQ09NT0RPUlNBRG9tYWluVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNybDCB +hQYIKwYBBQUHAQEEeTB3ME8GCCsGAQUFBzAChkNodHRwOi8vY3J0LmNvbW9kb2Nh +LmNvbS9DT01PRE9SU0FEb21haW5WYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0 +MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wOwYDVR0RBDQw +MoIVYWxwaGEuZWRpdG9yLnA1anMub3Jnghl3d3cuYWxwaGEuZWRpdG9yLnA1anMu +b3JnMA0GCSqGSIb3DQEBCwUAA4IBAQBkCt6uLnJGfgGVPMYmHk83hc8ZlOsVz+CM +aee//8V98w593JHxxsgCcbqB5vkMmWMvNyooSxpwSAciYidkaHs4GseM100aKP89 +dbJ2fT9DlCn5yxkgIEmyKryFw+dov0BmL6G21lVTludgQCYpB1TYF+al/c0RprRl +ysUfE1IkkZC84RDJefVF9VtPWZMPEWmKPf95gllAyHvN9rM24bbbmJPY0IvBoxho +1O/YeeXAEjtKyPQaFx+SH4i3v1u2fyfIslk7t072z7Xnl7K3i1qUDLUKssLgMcJY +AOpA7BEBaPfV06px0K5RLCp2tLLuU2kedrHqx4LCYNxuB7HbSdTD +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGCDCCA/CgAwIBAgIQKy5u6tl1NmwUim7bo3yMBzANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMjEy +MDAwMDAwWhcNMjkwMjExMjM1OTU5WjCBkDELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxNjA0BgNVBAMTLUNPTU9ETyBSU0EgRG9tYWluIFZh +bGlkYXRpb24gU2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAI7CAhnhoFmk6zg1jSz9AdDTScBkxwtiBUUWOqigwAwCfx3M28Sh +bXcDow+G+eMGnD4LgYqbSRutA776S9uMIO3Vzl5ljj4Nr0zCsLdFXlIvNN5IJGS0 +Qa4Al/e+Z96e0HqnU4A7fK31llVvl0cKfIWLIpeNs4TgllfQcBhglo/uLQeTnaG6 +ytHNe+nEKpooIZFNb5JPJaXyejXdJtxGpdCsWTWM/06RQ1A/WZMebFEh7lgUq/51 +UHg+TLAchhP6a5i84DuUHoVS3AOTJBhuyydRReZw3iVDpA3hSqXttn7IzW3uLh0n +c13cRTCAquOyQQuvvUSH2rnlG51/ruWFgqUCAwEAAaOCAWUwggFhMB8GA1UdIwQY +MBaAFLuvfgI9+qbxPISOre44mOzZMjLUMB0GA1UdDgQWBBSQr2o6lFoL2JDqElZz +30O0Oija5zAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNV +HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGwYDVR0gBBQwEjAGBgRVHSAAMAgG +BmeBDAECATBMBgNVHR8ERTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9kb2NhLmNv +bS9DT01PRE9SU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggrBgEFBQcB +AQRlMGMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9E +T1JTQUFkZFRydXN0Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21v +ZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggIBAE4rdk+SHGI2ibp3wScF9BzWRJ2p +mj6q1WZmAT7qSeaiNbz69t2Vjpk1mA42GHWx3d1Qcnyu3HeIzg/3kCDKo2cuH1Z/ +e+FE6kKVxF0NAVBGFfKBiVlsit2M8RKhjTpCipj4SzR7JzsItG8kO3KdY3RYPBps +P0/HEZrIqPW1N+8QRcZs2eBelSaz662jue5/DJpmNXMyYE7l3YphLG5SEXdoltMY +dVEVABt0iN3hxzgEQyjpFv3ZBdRdRydg1vs4O2xyopT4Qhrf7W8GjEXCBgCq5Ojc +2bXhc3js9iPc0d1sjhqPpepUfJa3w/5Vjo1JXvxku88+vZbrac2/4EjxYoIQ5QxG +V/Iz2tDIY+3GH5QFlkoakdH368+PUq4NCNk+qKBR6cGHdNXJ93SrLlP7u3r7l+L4 +HyaPs9Kg4DdbKDsx5Q5XLVq4rXmsXiBmGqW5prU5wfWYQ//u+aen/e7KJD2AFsQX +j4rBYKEMrltDR5FL1ZoXX/nUh8HCjLfn4g8wGTeGrODcQgPmlKidrv0PJFGUzpII +0fxQ8ANAe4hZ7Q7drNJ3gjTcBpUC2JD5Leo31Rpg0Gcg19hCC0Wvgmje3WYkN5Ap +lBlGGSW4gNfL1IYoakRwJiNiqZ+Gb7+6kHDSVneFeO/qJakXzlByjAA6quPbYzSf ++AZxAeKCINT+b72x +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFdDCCBFygAwIBAgIQJ2buVutJ846r13Ci/ITeIjANBgkqhkiG9w0BAQwFADBv +MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk +ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF +eHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFow +gYUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO +BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYD +VQQDEyJDT01PRE8gUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkq +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkehUktIKVrGsDSTdxc9EZ3SZKzejfSNw +AHG8U9/E+ioSj0t/EFa9n3Byt2F/yUsPF6c947AEYe7/EZfH9IY+Cvo+XPmT5jR6 +2RRr55yzhaCCenavcZDX7P0N+pxs+t+wgvQUfvm+xKYvT3+Zf7X8Z0NyvQwA1onr +ayzT7Y+YHBSrfuXjbvzYqOSSJNpDa2K4Vf3qwbxstovzDo2a5JtsaZn4eEgwRdWt +4Q08RWD8MpZRJ7xnw8outmvqRsfHIKCxH2XeSAi6pE6p8oNGN4Tr6MyBSENnTnIq +m1y9TBsoilwie7SrmNnu4FGDwwlGTm0+mfqVF9p8M1dBPI1R7Qu2XK8sYxrfV8g/ +vOldxJuvRZnio1oktLqpVj3Pb6r/SVi+8Kj/9Lit6Tf7urj0Czr56ENCHonYhMsT +8dm74YlguIwoVqwUHZwK53Hrzw7dPamWoUi9PPevtQ0iTMARgexWO/bTouJbt7IE +IlKVgJNp6I5MZfGRAy1wdALqi2cVKWlSArvX31BqVUa/oKMoYX9w0MOiqiwhqkfO +KJwGRXa/ghgntNWutMtQ5mv0TIZxMOmm3xaG4Nj/QN370EKIf6MzOi5cHkERgWPO +GHFrK+ymircxXDpqR+DDeVnWIBqv8mqYqnK8V0rSS527EPywTEHl7R09XiidnMy/ +s1Hap0flhFMCAwEAAaOB9DCB8TAfBgNVHSMEGDAWgBStvZh6NLQm9/rEJlTvA73g +JMtUGjAdBgNVHQ4EFgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQD +AgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAGBgRVHSAAMEQGA1UdHwQ9 +MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9BZGRUcnVzdEV4dGVy +bmFsQ0FSb290LmNybDA1BggrBgEFBQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6 +Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggEBAGS/g/FfmoXQ +zbihKVcN6Fr30ek+8nYEbvFScLsePP9NDXRqzIGCJdPDoCpdTPW6i6FtxFQJdcfj +Jw5dhHk3QBN39bSsHNA7qxcS1u80GH4r6XnTq1dFDK8o+tDb5VCViLvfhVdpfZLY +Uspzgb8c8+a4bmYRBbMelC1/kZWSWfFMzqORcUx8Rww7Cxn2obFshj5cqsQugsv5 +B5a6SE2Q8pTIqXOi6wZ7I53eovNNVZ96YUWYGGjHXkBrI/V5eu+MtWuLt29G9Hvx +PUsE2JOAWVrgQSQdso8VYFhH2+9uRv0V9dlfmrPb2LjkQLPNlzmuhbsdjrzch5vR +pu/xO28QOG8= +-----END CERTIFICATE----- diff --git a/client/modules/IDE/components/Preview.js b/client/modules/IDE/components/Preview.js deleted file mode 100644 index 5db7d07f..00000000 --- a/client/modules/IDE/components/Preview.js +++ /dev/null @@ -1,24 +0,0 @@ -import React, { PropTypes } from 'react'; - -class Preview extends React.Component { - componentDidMount() { - - } - - render() { - return ( -
- - -
- ); - } -} - -Preview.propTypes = { - content: PropTypes.string.isRequired -}; - -export default Preview; diff --git a/client/modules/IDE/components/PreviewFrame.js b/client/modules/IDE/components/PreviewFrame.js index 434ae9c1..892bf1c9 100644 --- a/client/modules/IDE/components/PreviewFrame.js +++ b/client/modules/IDE/components/PreviewFrame.js @@ -148,6 +148,7 @@ class PreviewFrame extends React.Component { // one level down... htmlFile = hijackConsoleLogsScript() + htmlFile; + const mediaFiles = this.props.files.filder(file => file.url); const jsFiles = []; this.props.jsFiles.forEach(jsFile => { @@ -158,13 +159,9 @@ class PreviewFrame extends React.Component { jsFileStrings.forEach(jsFileString => { if (jsFileString.match(jsFileRegex)) { const filePath = jsFileString.substr(1, jsFileString.length - 2); - let fileName = filePath; - if (fileName.match(/^\.\//)) { - fileName = fileName.substr(2, fileName.length - 1); - } else if (fileName.match(/^\//)) { - fileName = fileName.substr(1, fileName.length - 1); - } - this.props.files.forEach(file => { + const filePathArray = filePath.split('/'); + const fileName = filePathArray[filePathArray.length - 1]; + mediaFiles.forEach(file => { if (file.name === fileName) { newJSFile.content = newJSFile.content.replace(filePath, file.blobURL); // eslint-disable-line } diff --git a/server/controllers/embed.controller.js b/server/controllers/embed.controller.js new file mode 100644 index 00000000..b0e33b94 --- /dev/null +++ b/server/controllers/embed.controller.js @@ -0,0 +1,53 @@ +import Project from '../models/project'; +import escapeStringRegexp from 'escape-string-regexp'; +const startTag = '@fs-'; + +function injectMediaUrls(filesToInject, mediaFiles) { + filesToInject.forEach(file => { + let fileStrings = file.content.match(/(['"])((\\\1|.)*?)\1/gm); + const fileStringRegex = /^('|")(?!(http:\/\/|https:\/\/)).*('|")$/i; + fileStrings = fileStrings || []; + fileStrings.forEach(fileString => { + //if string does not begin with http or https + if (fileString.match(fileStringRegex)) { + const filePath = fileString.substr(1, fileString.length - 2); + const filePathArray = filePath.split('/'); + const fileName = filePathArray[filePathArray.length - 1]; + mediaFiles.forEach(mediaFile => { + if (mediaFile.name === fileName) { + file.content = file.content.replace(filePath, mediaFile.url); + } + }) + } + }); + }); +} + +export function serveProject(req, res) { + Project.findById(req.params.project_id) + .exec((err, project) => { + const files = project.files; + let htmlFile = files.find(file => file.name.match(/\.html$/i)).content; + const jsFiles = files.filter(file => file.name.match(/\.js$/i)); + const cssFiles = files.filter(file => file.name.match(/\.css$/i)); + const mediaFiles = files.filter(file => file.url); + + injectMediaUrls(jsFiles, mediaFiles); + injectMediaUrls(cssFiles, mediaFiles); + + jsFiles.forEach(jsFile => { + const fileName = escapeStringRegexp(jsFile.name); + const fileRegex = new RegExp(`([\s\S]*?)<\/script>`, 'gmi'); + const replacementString = ``; + htmlFile = htmlFile.replace(fileRegex, replacementString); + }); + + cssFiles.forEach(cssFile => { + const fileName = escapeStringRegexp(cssFile.name); + const fileRegex = new RegExp(``, 'gmi'); + htmlFile = htmlFile.replace(fileRegex, ``); + }); + + res.send(htmlFile); + }); +} \ No newline at end of file diff --git a/server/routes/embed.routes.js b/server/routes/embed.routes.js new file mode 100644 index 00000000..b3a98b6a --- /dev/null +++ b/server/routes/embed.routes.js @@ -0,0 +1,8 @@ +import { Router } from 'express'; +import * as EmbedController from '../controllers/embed.controller'; + +const router = new Router(); + +router.route('/embed/:project_id').get(EmbedController.serveProject); + +export default router; diff --git a/server/server.js b/server/server.js index 7cf315da..12900566 100644 --- a/server/server.js +++ b/server/server.js @@ -30,6 +30,7 @@ import projects from './routes/project.routes'; import files from './routes/file.routes'; import aws from './routes/aws.routes'; import serverRoutes from './routes/server.routes'; +import embedRoutes from './routes/embed.routes'; // Body parser, cookie parser, sessions, serve public assets @@ -62,6 +63,8 @@ app.use('/api', aws); // this is supposed to be TEMPORARY -- until i figure out // isomorphic rendering app.use('/', serverRoutes); + +app.use('/', embedRoutes); app.get('/auth/github', passport.authenticate('github')); app.get('/auth/github/callback', passport.authenticate('github', { failureRedirect: '/login' }), (req, res) => { res.redirect('/');