kintone UI Component と CryptoJS でレコードの内容を暗号化する秘密のアプリを作る

今回は、
CryptoJS と kintone UI Component を使って、フィールドを暗号化するアプリを作ってみたいと思います。

# 出来上がりの動画

<iframe width="480" height="360" src="https://www.youtube.com/embed/0yoYOIFD5l8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


# アプリの準備

フィールドは２つだけ

| フィールド種類 | フィールドコード | 
|:-:|:-:|
|スペース|sp|
| 文字列(1行)  |  秘密のフィールド |   


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/67584583-b0cf-aeeb-9941-efcf764069f5.png)


# JavaScript 


**CryptoJS**
こちらからCryptoJSのCDNをコピーして「JavaScript / CSSでカスタマイズ」にコピーします。

https://cdnjs.com/libraries/crypto-js

私がコピーしたのはこちら。
`https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js`

**kintone UI Component**

kintone UI Component も追加します。

`https://unpkg.com/kintone-ui-component/umd/kuc.min.js`

## レコード追加・編集画面の表示後イベント

```js
kintone.events.on(
  ["app.record.create.show", "app.record.edit.show"],
  (event) => {
    const headsp = kintone.app.record.getHeaderMenuSpaceElement();

    const txt = new Kuc.Text({
      label: "秘密の暗号",
      visible: true,
      disabled: false,
    });
    headsp?.appendChild(txt);

    const btn = new Kuc.Button({
      text: "暗号化",
      type: "submit",
    });
    headsp?.appendChild(btn);

    const sp = kintone.app.record.getSpaceElement("sp");
    const r_txt1 = new Kuc.Text({
      label: "名前",
      visible: true,
      disabled: false,
    });
    sp?.appendChild(r_txt1);
    const r_txt2 = new Kuc.Text({
      label: "住所",
      visible: true,
      disabled: false,
    });
    sp?.appendChild(r_txt2);

    btn.addEventListener("click", () => {
      const obj = {
        r_txt1: { value: r_txt1.value },
        r_txt2: { value: r_txt2.value },
      };

      const jsonStr = JSON.stringify(obj);
      const encrypted = CryptoJS.AES.encrypt(jsonStr, txt.value);
      const aesStr = encrypted.toString();

      const robj = kintone.app.record.get();
      robj.record.秘密のフィールド.value = aesStr;
      kintone.app.record.set(robj);
    });

    return event;
  }
);
```

## レコード詳細画面の表示後イベント

```js
kintone.events.on(["app.record.detail.show"], (event) => {
  const headsp = kintone.app.record.getHeaderMenuSpaceElement();

  const txt = new Kuc.Text({
    label: "秘密の暗号",
    visible: true,
    disabled: false,
  });
  headsp?.appendChild(txt);

  const btn = new Kuc.Button({
    text: "複合",
    type: "submit",
  });
  headsp?.appendChild(btn);

  const sp = kintone.app.record.getSpaceElement("sp");
  const r_txt1 = new Kuc.Text({
    label: "名前",
    visible: true,
    disabled: true,
  });
  sp?.appendChild(r_txt1);
  const r_txt2 = new Kuc.Text({
    label: "住所",
    visible: true,
    disabled: true,
  });
  sp?.appendChild(r_txt2);

  btn.addEventListener("click", async () => {
    const decrypted = CryptoJS.AES.decrypt(
      event.record.秘密のフィールド.value,
      txt.value
    );

    const dec = decrypted.toString(CryptoJS.enc.Utf8);

    if (dec === "") {
      txt.error = "暗号が違います";
    } else {
      txt.error = "";
      const obj = JSON.parse(dec);
      r_txt1.value = obj.r_txt1.value;
      r_txt2.value = obj.r_txt2.value;
    }
  });

  return event;
});
```

# まとめ
秘密の交換日記などに使うといいかもしれませんね🤔（ほんとに？）

また、紹介したままのコードを使用するだけだと、上書きし放題、改ざんし放題なので、
交換日記などに使用した場合は、誰かのいたずらにより友情にひびが入る可能性もあります。
アクセス権なども上手に設定しましょう。

そして、秘密の暗号はどこにも保存されない、レコードを作成＆編集した人の心にしかないので忘れないように気をつけましょう。