eLabFTWを用いてmermaidを読み書きできるようにする

eLabFTWはオープンソースの優れたELNであるが、痒いところに手が届かない場合がある。そんなとき、自分で好きなJavaScriptを組み込むことができる。

### 　elabFTWコンテナへのアクセス
VS CodeでサーバーにSSH接続し、Dockerプラグインからコンテナへアクセスする。


### nginxの設定書き換え
elabimg/etc/nginx/common.confの内容を書き換える。書き換え場所は次のSecurity Headersの一部である。

```elabimg/etc/nginx/common.conf
# security headers
more_set_headers "Strict-Transport-Security: max-age=63072000";
more_set_headers "X-XSS-Protection: 0";
more_set_headers "X-Content-Type-Options: nosniff";
more_set_headers "Content-Security-Policy: default-src 'self' data:; script-src 'self' ; connect-src 'self' blob: https://get.elabftw.net; img-src 'self' data: blob:; style-src 'self' 'unsafe-inline'; font-src 'self' data:; object-src 'self'; base-uri 'none'; frame-ancestors 'none'";
more_set_headers "Referrer-Policy: no-referrer";
more_set_headers "Permissions-Policy: autoplay 'none'; camera 'self'; document-domain 'none'; encrypted-media 'none'; fullscreen 'self'; geolocation 'none'; microphone 'self'; midi 'none'; payment 'none'; vr 'none'";
more_set_headers "Vary: Accept-Encoding";
more_set_headers "Server: 29e";
```
このうちのCSPに関する設定を
```elabimg/etc/nginx/common.conf
# more_set_headers "Content-Security-Policy: default-src 'self' data:; script-src 'self' ; connect-src 'self' blob: https://get.elabftw.net; img-src 'self' data: blob:; style-src 'self' 'unsafe-inline'; font-src 'self' data:; object-src 'self'; base-uri 'none'; frame-ancestors 'none'";
more_set_headers "Content-Security-Policy: default-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com; connect-src 'self' blob: https://get.elabftw.net; img-src 'self' data: blob:; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://fonts.googleapis.com https://cdnjs.cloudflare.com; font-src 'self' data: https://fonts.gstatic.com https://cdn.jsdelivr.net; object-src 'self'; base-uri 'none'; frame-ancestors 'none';";
```
と書き換える。
このようにすることで、外部のライブラリから色々と読み込めるようになる。これを忘れると、外部からスクリプトを読もうとした時に、コンテンツセキュリティポリシー違反でブロックされるようになる。


次に、実装したいJavaScriptライブラリをsrc/templates/head.htmlに組み込む。
```src/templates/head.html
<head>
  <meta http-equiv='Content-type' content='text/html;charset=UTF-8' />
  <meta name='viewport' content='width=device-width, initial-scale=1'>
  <meta name='description' content='Electronic lab notebook - eLabFTW'>
  {% if App.Config.configArr.autologout_time != '0' %}
    <meta http-equiv='refresh' content='{{ App.Config.configArr.autologout_time }};url=app/logout.php' />
  {% endif %}
  <meta name='csrf-token' content='{{ App.Session.get('csrf') }}'/>
  <link rel='manifest' href='/manifest.webmanifest' crossorigin='use-credentials'>
  <link rel='icon' href='/assets/images/favicon.ico' sizes='any'>{# 32×32 #}
  <link rel='icon' href='/assets/images/favicon.svg' type='image/svg+xml'>
  <link rel='apple-touch-icon' href='/assets/images/apple-touch-icon.png'>{# 180×180 #}

  <title>{{ App.pageTitle }} - eLabFTW</title>
  {# see builder.js to see what gets inside these files #}
  {# CSS #}
  <link rel='stylesheet' media='all' href='/assets/vendor.min.css?v={{ v }}' />
  <link rel='stylesheet' media='all' href='/assets/elabftw.min.css?v={{ v }}' />

  {# all js dependencies bundled by webpack (see builder.js) #}
  <script defer src='/assets/vendor.bundle.js?v={{ v }}'></script>
  {# the main JS bundle with all the elabftw TS code (see builder.js) #}
  <script defer src='/assets/main.bundle.js?v={{ v }}'></script>

  #ここに好きなスクリプトを埋め込む
  <script src="https://cdn.jsdelivr.net/npm/mermaid@10.5.0/dist/mermaid.min.js" defer></script>
  <script>
    // ページが完全に読み込まれた後にMermaidを初期化する
    window.addEventListener('load', function() {
      mermaid.initialize({ startOnLoad: true });
    });
  </script>
</head>
```

dockerの中身を書き換えたあと、Webサーバーのキャッシュをクリアする必要がある。

```
   docker ps #コンテナリストの取得
   docker exec -it container_id  /bin/bash #コンテナの中に入る
   php bin/console cache:clear　#PHPキャッシュクリア
   nginx -s reload #NginXのリロード
```

以上で、JavaScriptが読み込まれるはず。

※本記事はコニカミノルタ株式会社　技術開発本部にて@yanamiと共に実施しました。本記事の公開は、コニカミノルタ技術開発本部先進コア技術センターにより外部発表許可を受けていますが、本コードは私及び@yanamiが構築したものであり、コニカミノルタ株式会社は本ページ記載の情報の利用に関して、一切の責任を負いません。