1use anyhow::Result;
8use deltachat_derive::{FromSql, ToSql};
9
10use crate::context::Context;
11use crate::tools::{create_id, time};
12
13#[derive(
15 Debug, Default, Display, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive, ToSql, FromSql,
16)]
17#[repr(u32)]
18pub enum Namespace {
19 #[default]
20 Unknown = 0,
21 Auth = 110,
22 InviteNumber = 100,
23}
24
25pub async fn save(
27 context: &Context,
28 namespace: Namespace,
29 foreign_key: Option<&str>,
30 token: &str,
31 timestamp: i64,
32) -> Result<()> {
33 if token.is_empty() {
34 info!(context, "Not saving empty {namespace} token");
35 return Ok(());
36 }
37 context
38 .sql
39 .execute(
40 "INSERT OR IGNORE INTO tokens (namespc, foreign_key, token, timestamp) VALUES (?, ?, ?, ?)",
41 (namespace, foreign_key.unwrap_or(""), token, timestamp),
42 )
43 .await?;
44 Ok(())
45}
46
47pub async fn lookup(
56 context: &Context,
57 namespace: Namespace,
58 foreign_key: Option<&str>,
59) -> Result<Option<String>> {
60 context
61 .sql
62 .query_get_value(
63 "SELECT token FROM tokens WHERE namespc=? AND foreign_key=? ORDER BY id DESC LIMIT 1",
64 (namespace, foreign_key.unwrap_or("")),
65 )
66 .await
67}
68
69pub async fn lookup_or_new(
70 context: &Context,
71 namespace: Namespace,
72 foreign_key: Option<&str>,
73) -> Result<String> {
74 if let Some(token) = lookup(context, namespace, foreign_key).await? {
75 return Ok(token);
76 }
77
78 let token = create_id();
79 let timestamp = time();
80 save(context, namespace, foreign_key, &token, timestamp).await?;
81 Ok(token)
82}
83
84pub async fn exists(context: &Context, namespace: Namespace, token: &str) -> Result<bool> {
85 let exists = context
86 .sql
87 .exists(
88 "SELECT COUNT(*) FROM tokens WHERE namespc=? AND token=?;",
89 (namespace, token),
90 )
91 .await?;
92 Ok(exists)
93}
94
95pub async fn delete(context: &Context, foreign_key: &str) -> Result<()> {
100 context
101 .sql
102 .execute("DELETE FROM tokens WHERE foreign_key=?", (foreign_key,))
103 .await?;
104 Ok(())
105}