pebble_cms/services/
preview.rs1use crate::Database;
5use anyhow::Result;
6use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
7use rand::RngCore;
8
9const PREVIEW_TOKEN_LIFETIME_SECS: i64 = 3600;
11
12pub fn generate_preview_token(db: &Database, content_id: i64) -> Result<String> {
15 let mut random_bytes = [0u8; 16];
16 rand::rngs::OsRng.fill_bytes(&mut random_bytes);
17 let token = URL_SAFE_NO_PAD.encode(random_bytes);
18
19 let conn = db.get()?;
20 conn.execute(
21 "INSERT INTO preview_tokens (token, content_id, expires_at) VALUES (?, ?, datetime('now', ?||' seconds'))",
22 (&token, content_id, PREVIEW_TOKEN_LIFETIME_SECS),
23 )?;
24
25 Ok(token)
26}
27
28pub fn validate_preview_token(db: &Database, token: &str) -> Result<Option<i64>> {
30 let conn = db.get()?;
31 let content_id: Option<i64> = conn
32 .query_row(
33 "SELECT content_id FROM preview_tokens WHERE token = ? AND expires_at > datetime('now')",
34 [token],
35 |row| row.get(0),
36 )
37 .ok();
38 Ok(content_id)
39}
40
41pub fn cleanup_expired_tokens(db: &Database) -> Result<usize> {
43 let conn = db.get()?;
44 let count = conn.execute(
45 "DELETE FROM preview_tokens WHERE expires_at <= datetime('now')",
46 [],
47 )?;
48 Ok(count)
49}