Nextcloudを使ったWebサイトをユーザーとして使っています。
Edge拡張機能からAPIを使ってみます。
ポップアップUIでパスワード保護と有効期限を設定し、ファイルを選択するだけで、以下をまとめて実行します。
- WebDAV API でファイルをアップロード
- OCS Share API で公開共有リンクを作成
- 作成したリンクにパスワード・有効期限を設定
- 共有URLをクリップボードにコピー
Edgeストアで公開しています:
Edge拡張機能
拡張機能のボタンクリックでポップアップを呼び出して、パスワード・有効期限を入力する。
ファイルを選択することで、ファイルをアップロードして各設定が入ります。
API処理の流れ
1. ファイルアップロード(WebDAV)
Nextcloudは/remote.php/webdav/{path}エンドポイントでWebDAVを提供しています。
PUTメソッドでファイルを送信します。
const res = await fetch(base + encodePath(name), {
method: "PUT",
credentials: "include", // セッションCookieを送信
headers: Object.assign({
"Content-Type": file.type || "application/octet-stream",
"If-None-Match": "*",
}, authHeaders()),
body: buffer,
});
2. 共有リンクの作成
リンク作成と合わせてパスワード・有効期限の設定も行います。
shareType:3 → 公開リンク共有
permissions:1 → 読み取り専用
password:パスワード
expireDate:有効期限 既定値は一週間後 空欄で無期限
const createShare = (remoteName) => {
const form = new FormData();
form.append("path", "/" + remoteName);
form.append("shareType", "3");
form.append("permissions", "1");
if (password) form.append("password", password);
if (expireDate) form.append("expireDate", expireDate);
return ocsFetch("/ocs/v2.php/apps/files_sharing/api/v1/shares?format=json", {
method: "POST",
body: form,
});
};
- 作成後に
PUT/shares/{id}で後追い設定はしていません - 後追いだと設定が入るまでの間、無防備な公開リンクが実在してしまう
- また
application/x-www-form-urlencodedでないと本文は無視され; charset=UTF-8が付くだけで400 Bad Requestになるため
3. 共有URLをクリップボードにコピー
共有URLをすぐ使用できるようにクリップボードへコピーします。
const shareUrl = share.url;
let copied = false;
try {
// ポップアップにフォーカスがあると失敗するため、成否を呼び出し元へ返す。
await navigator.clipboard.writeText(shareUrl);
copied = true;
} catch { /* コピー失敗はリンク表示でフォローする */ }
const box = toast(copied ? "共有リンクをコピーしました" : "共有リンクを作成しました", shareUrl);
オリジンの承認
初めて使うサイトでは確認のためもう一度ボタンを押す必要があります。
承認したオリジンはchrome.storage.syncに保存され、次回以降は確認なしで実行されます。
登録済みのサイトは ポップアップ下部に一覧表示されるので「削除」できます。
Nextcloudと判定できないページでも、警告を確認したうえで登録して実行できます(ボタンが「警告を承知で登録して続行」に変わります)。
判定はあくまで誤操作防止の目安で、続行するかどうかはユーザーが決める設計です。
セキュリティ・運用について
| 項目 | 説明 |
|---|---|
| Credentialの取り扱い | credentials: "include" でユーザーのログインセッションCookieを自動送信しています。 これにより、別途Bearerトークンを管理する必要がなく、Nextcloudにログイン済みであればそのままAPIが使えます。 |
| HTTP Only / Secure | Nextcloud側でCookieのセキュア設定がされている場合、HTTPS通信が必須になります。 HTTPSのサイトで使用することを推奨します。 |
| requesttokenの有効期限 | Nextcloudのrequesttokenはセッション単位で管理されます。 長時間放置後に失効した場合、ページリロードで再取得が必要です。 |
| パスワードの受け渡し | パスワードは保存せず、承認したサイトのNextcloud APIへのみ送信します。 拡張機能側でHTTPSを強制していないため、HTTPSで暗号化されるかどうかはサイトの設定によります。 |
マニフェスト
popup.htmlが入力/実行の起点となります。
Nextcloud APIを使用したサイトを想定しているため、ドメインは不定となります。
そのためcontent_scriptsやhost_permissionsでのドメイン指定はしていません。
その代わり、activeTabとchrome.scripting.executeScriptで、拡張機能のアイコンを押したタブにだけ、その時だけスクリプトを注入します。
合わせて、オリジンの承認のような運用としています。
{
"manifest_version": 3,
"name": "Nextcloud-Quick-Share",
"version": "1.2.0",
"description": "現在開いている Nextcloud のページからファイルをアップロードし、共有リンクを作成します。",
"permissions": ["activeTab", "scripting", "storage"],
"background": {
"service_worker": "src/background.js"
},
"icons": {
"16": "icon/icon-16.png",
"32": "icon/icon-32.png",
"48": "icon/icon-48.png",
"128": "icon/icon-128.png"
},
"action": {
"default_popup": "src/popup.html",
"default_title": "Nextcloud-Quick-Share",
"default_icon": {
"16": "icon/icon-16.png",
"32": "icon/icon-32.png",
"48": "icon/icon-48.png",
"128": "icon/icon-128.png"
}
}
}
ポップアップ
ユーザーが入力するUI部分となっています。
パスワードと有効期限を入れてファイル選択画面を開きます。
おわり
これで日々の地味なストレスを解消できるかもしれません。
実際に使用する際は、サイト側で禁止されてないかなどの注意は必要です。