feat(page-data): complete Phase 4-5, ops UI, and publish integration
Add visitor roles, row-level scope, owner ops APIs, MySQL policy index, Turnstile captcha, browser client SDK, publish-panel dataset binding, acceptance tests, and usage documentation. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -41,6 +41,34 @@ export function createPageDataSessionStore(options = {}) {
|
||||
return sessions.delete(hashToken(token));
|
||||
}
|
||||
|
||||
function revokeByPageId(pageId) {
|
||||
let count = 0;
|
||||
for (const [key, session] of sessions.entries()) {
|
||||
if (session.pageId === pageId) {
|
||||
sessions.delete(key);
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
function listByPageId(pageId) {
|
||||
const now = Date.now();
|
||||
const active = [];
|
||||
for (const session of sessions.values()) {
|
||||
if (session.pageId !== pageId) continue;
|
||||
if (session.expiresAt <= now) continue;
|
||||
active.push({
|
||||
sessionId: session.sessionId,
|
||||
pageId: session.pageId,
|
||||
ownerUserId: session.ownerUserId,
|
||||
accessMode: session.accessMode,
|
||||
expiresAt: session.expiresAt,
|
||||
});
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
function clearExpired() {
|
||||
const now = Date.now();
|
||||
for (const [key, session] of sessions.entries()) {
|
||||
@@ -48,7 +76,7 @@ export function createPageDataSessionStore(options = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
return { issue, verify, revoke, clearExpired };
|
||||
return { issue, verify, revoke, revokeByPageId, listByPageId, clearExpired };
|
||||
}
|
||||
|
||||
export function createPageDataRateLimiter(options = {}) {
|
||||
|
||||
Reference in New Issue
Block a user