結論
- putなどのメソッドにあるoptionでexpireInの指定をした場合登録される相対時間はサーバーの時間でなく、ローカルの時間。
そのため、実際に削除される時間は想定よりサーバー時間とローカル時間のずれ分ずれてしまう - put、putMany、insertはデータフィールドとoptionでexpireInを指定した場合、optionが優先される
- updateの場合、
- set operationで__expiresを指定した場合、データフィールドが優先されてしまう
- increment operationで__expiresを指定した場合、重複のデータを変更しようとするエラーが発生する
やったこと
Deta Baseの予約データ__expiresに関してJavaScriptで検証を行いました。
確認したdetaのバージョンは以下の通りです。
"dependencies": {
"deta": "^1.1.0"
}
Deta Baseとは
Deta Baseとはdeta.shのサービスのひとつです。
データを格納することができ、NoSQLデータベースの一種です。
予約データ__expiresとは
Deta Baseのデータを保持する期限です。
Unixタイム時間で管理されており、超えると自動で削除されます。
データを設定する際にoptionとして設定できます。
検証
各章は、実行コード、結果の順に記載していきます。
データフィールドとexpireInオプションを同時に設定した場合
db.put(
{
__expires: 1000,
},
"data1",
{ expireIn: 100 }
);
__expiresにはopttionで指定した時間が設定されていました。
putMany、insertも同様。
option設定したときに設定される時間はサーバの時間か、ローカルの時間か
db.put(
{
__expires: Date.now() / 1000 + 60,
},
"data2"
);
db.put(
{
data: "data",
},
"data3",
{ expireIn: 60 }
);
同じ__expiresが登録されました。
option指定してもローカル時間で登録される模様。
updateのset operationで__expiresをセットした場合
{
const { __expires } = await db.put(
{
__expires: "data",
},
"data",
{ expireIn: 600 }
);
// putした時の時間:1663328394
console.log(__expires);
}
{
const updates = {
__expires: Date.now() / 1000 + 200, // 200秒後なので相対的に400秒早い
};
await db.update(updates, "data", { expireIn: 600 });
const { __expires } = await db.get("data");
// updateした時の時間:1663327994
console.log(__expires);
}
putした後の時間1663328394
からupdateした後の時間1663327994
でちょうど400小さくなっている。
updateのincrement operationで__expiresをセットした場合
const updates = {
__expires: db.util.increment(1000),
};
db.update(updates, "data", { expireIn: 600 });
例外発生
/home/path/to/projet/node_modules/deta/dist/index.js:187
error: new Error(message),
^
Error: Bad request: Conflicting operations on common attribute(s)
まとめ
予約データの__expiresをユーザーが直接いじるのは、悪意があるのでおいておくにしても、
expireInで登録される時間が、サーバー時間でなくローカル時間なのは罠だと思います。
おまけ
データフィールドに__expiresを現在でセットした場合
db.put(
{
__expires: Date.now() / 1000,
},
"data"
);
確認される前に削除されていました。
自分でもきちんと設定できる模様。
データフィールドの__expiresをStringにした場合
実行コード
db.put(
{
__expires: "data",
},
"data"
);
例外発生
/home/path/to/project/node_modules/deta/dist/index.js:187
error: new Error(message),
^
Error: Bad expiration timestamp