# What are the correct steps to import the scripts?

**URL:** <https://devforum.zoom.us/t/what-are-the-correct-steps-to-import-the-scripts/82047>\
**Category:** Zoom Apps\
**Created:** [January 24, 2023, 7:46pm UTC](https://devforum.zoom.us/t/what-are-the-correct-steps-to-import-the-scripts/82047 "2023-01-24T19:46:52Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jsarmiento](https://avatars.discourse-cdn.com/v4/letter/j/aca169/32.png) [@jsarmiento](https://devforum.zoom.us/u/jsarmiento)\
**Post date:** [January 24, 2023, 7:46pm UTC](https://devforum.zoom.us/t/what-are-the-correct-steps-to-import-the-scripts/82047/1 "2023-01-24T19:46:52Z")

</div>

### Before Creating a New Topic:

Actually, we are creating a custom design application and we need to import custom scripts (internal and external), so far we are having trouble implementing the chart.js library and exporting a custom .js file

This is the mistake  
` Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src-attr 'none'". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution. Note that hashes do not apply to event handlers, style attributes and javascript: navigations unless the 'unsafe-hashes' keyword is present.`

### External Scripts

we add the scripts to the content security policy

```auto
    contentSecurityPolicy: {
        directives: {
            'default-src': 'self',
            styleSrc: ["https://fonts.googleapis.com", "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.2.0/chart.umd.js", "sha512-B51MzT4ksAo6Y0TcUpmvZnchoPYfIcHadIaFqV5OR5JAh6dneYAeYT1xIlaNHhhFAALd5FLDTWNt/fkxhwE/oQ==", "https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/2.0.0/chartjs-plugin-zoom.min.js'", 'https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js', "sha512-B6F98QATBNaDHSE7uANGo5h0mU6fhKCUD+SPAY7KZDxE8QgZw9rewDtNiu3mbbutYDWOKT3SPYD8qDBpG2QnEg==", "nonce-2726c7f26c",],
            scriptSrc: ["https://appssdk.zoom.us/sdk.min.js", "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.2.0/chart.umd.js", "sha512-B51MzT4ksAo6Y0TcUpmvZnchoPYfIcHadIaFqV5OR5JAh6dneYAeYT1xIlaNHhhFAALd5FLDTWNt/fkxhwE/oQ==", "https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/2.0.0/chartjs-plugin-zoom.min.js'", "'https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js'","sha512-B6F98QATBNaDHSE7uANGo5h0mU6fhKCUD+SPAY7KZDxE8QgZw9rewDtNiu3mbbutYDWOKT3SPYD8qDBpG2QnEg==", "nonce-2726c7f26c",],
            imgSrc: [`https://${redirectHost}`],
            'connect-src': 'self',
            'base-uri': 'self',
            'form-action': 'self',
        },
    }, `

```

### Internal Scripts

I create A file in /dist/js folder as contro\_manager.js

and imprt using  
`script(src='/js/control_manager.js')`

---

<div class="post-metadata">

**Author:** ![chrisewald](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/chrisewald/32/42118_2.png) [@chrisewald](https://devforum.zoom.us/u/chrisewald)\
**Post date:** [January 24, 2023, 8:36pm UTC](https://devforum.zoom.us/t/what-are-the-correct-steps-to-import-the-scripts/82047/2 "2023-01-24T20:36:37Z")

</div>

Hi @jose.sarmiento,

Are you using a package to create the CSP headers? If so, I would check out that package’s documentation.

In the case you are not using a separate package, the syntax is not correct. Raw CSP headers are strings that use semicolons to separate parts. You also do not need shas at all - that is an additional optional security feature.

See here for how the example app sets CSP headers: [zoomapps-advancedsample-react/middleware.js at d4c7c9a3001a57b8b4e5e93b727d7babb8dffd31 · zoom/zoomapps-advancedsample-react · GitHub](https://github.com/zoom/zoomapps-advancedsample-react/blob/d4c7c9a3001a57b8b4e5e93b727d7babb8dffd31/backend/middleware.js#L15-L18)

---

<div class="post-metadata">

**Author:** ![MaxM](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/maxm/32/42303_2.png) [@MaxM](https://devforum.zoom.us/u/MaxM)\
**Post date:** [January 24, 2023, 10:33pm UTC](https://devforum.zoom.us/t/what-are-the-correct-steps-to-import-the-scripts/82047/3 "2023-01-24T22:33:06Z")

</div>

That’s right, you should be using a nonce or a hash but not both. If you use just one do you get the same error?

Please see this document for more information:

> **[How To Secure Node.js Applications with a Content Security Policy |...](https://www.digitalocean.com/community/tutorials/how-to-secure-node-js-applications-with-a-content-security-policy#step-4-handling-inline-sources)**
>
> A CSP is an HTTP header that provides an extra layer of security against code-injection attacks, such as cross-site scripting (XSS), clickjacking, and other …

In most cases, using the SHA hash should be the easiest to implement.

If you want to use a nonce, you can generate it uniquely and use it both in the CSP header and the client code.

Using the [Basic Sample App](https://github.com/zoom/zoomapps-sample-js) as an example:

**app.js**  
Generate a nonce

```auto
// generate a nonce for inlining scripts and styles
app.use((req, res, next) => {
    res.locals.cspNonce = crypto.randomBytes(16).toString('hex');
    next();
});

//...

const headers = {
    frameguard: {
        action: 'sameorigin',
    },
    hsts: {
        maxAge: 31536000,
    },
    referrerPolicy: 'same-origin',
    contentSecurityPolicy: {
        directives: {
            'default-src': 'self',
            styleSrc: [
                "'self'",
                (req, res) => `'nonce-${res.locals.cspNonce}'`,
            ],
            scriptSrc: [
                "'self'",
                (req, res) => `'nonce-${res.locals.cspNonce}'`,
            ],
            imgSrc: ["'self'", `https://${redirectHost}`],
            'connect-src': 'self',
            'base-uri': 'self',
            'form-action': 'self',
        },
    },
};

```

**server/routes/index.js**  
Change the route to return the nonce you created

```auto
//...
        return res.render('index', {
            nonce: res.locals.cspNonce
            isZoom,
            title: `Hello ${name}`,
        });

```

**server/views/index.pug**  
Use the variable in the client template

```plaintext
append scripts
    if isZoom
        script(nonce=nonce src='https://example.com/dep.js')
        script(type="module" src='/js/bundle.mjs')
        script(nomodule src='/js/bundle.js')

```

I hope that helps!

---

<div class="post-metadata">

**Author:** ![jsarmiento](https://avatars.discourse-cdn.com/v4/letter/j/aca169/32.png) [@jsarmiento](https://devforum.zoom.us/u/jsarmiento)\
**Post date:** [January 25, 2023, 8:18pm UTC](https://devforum.zoom.us/t/what-are-the-correct-steps-to-import-the-scripts/82047/4 "2023-01-25T20:18:38Z")

</div>

Hi @MaxM , Yeah, you are right

When I put only the chart.js in the app header and copy/paste the sha-code and put in the index.pug the same sha-code, works.

And when only use once encode, there a problem in the console

`  
Refused to load the script

> ‘[https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.2.0/chart.umd.js](https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.2.0/chart.umd.js)’ because it violates the following Content Security Policy directive: “script-src ‘self’ ‘nonce-a6c00292f4c795e4f0f0739f4a52585f’”. Note that ‘script-src-elem’ was not explicitly set, so ‘script-src’ is used as a fallback.

`

---

<div class="post-metadata">

**Author:** ![jsarmiento](https://avatars.discourse-cdn.com/v4/letter/j/aca169/32.png) [@jsarmiento](https://devforum.zoom.us/u/jsarmiento)\
**Post date:** [January 25, 2023, 8:31pm UTC](https://devforum.zoom.us/t/what-are-the-correct-steps-to-import-the-scripts/82047/5 "2023-01-25T20:31:08Z")

</div>

si por ejemplo,quiero añadir eventos personalizados, deberia hacer lo siguiente?=\>

1. Crear un .js con a funciones personalizadas  
ejemplo public\js\lib\control\_manager.js

```auto
function myFunction(){
    const paragraph = document.getElementById('paragraph');
    // Event when the button is clicked
    paragraph.innerHTML = "new paragraph;";
}
export {myFunction}

```

1. importar en el index.js  
public\js\index.js

```auto
import { myFunction } from "./lib/control_manager.js"

```

1. And the import/ad event in the index .pug

```auto

button(id="myButton" onclick="myFunction()") click me

```

In this case the budle.js is no a module

---

<div class="post-metadata">

**Author:** ![MaxM](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/maxm/32/42303_2.png) [@MaxM](https://devforum.zoom.us/u/MaxM)\
**Post date:** [January 25, 2023, 10:12pm UTC](https://devforum.zoom.us/t/what-are-the-correct-steps-to-import-the-scripts/82047/6 "2023-01-25T22:12:39Z")

</div>

> [@jsarmiento](#):
>
> “script-src ‘self’ ‘nonce-a6c00292f4c795e4f0f0739f4a52585f’”.

Make sure that you are still adding the URL along with the nonce to the script-src
