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 context
34 .sql
35 .execute(
36 "INSERT INTO tokens (namespc, foreign_key, token, timestamp) VALUES (?, ?, ?, ?)",
37 (namespace, foreign_key.unwrap_or(""), token, timestamp),
38 )
39 .await?;
40 Ok(())
41}
42
43pub async fn lookup(
52 context: &Context,
53 namespace: Namespace,
54 foreign_key: Option<&str>,
55) -> Result<Option<String>> {
56 context
57 .sql
58 .query_get_value(
59 "SELECT token FROM tokens WHERE namespc=? AND foreign_key=? ORDER BY timestamp DESC LIMIT 1",
60 (namespace, foreign_key.unwrap_or("")),
61 )
62 .await
63}
64
65pub async fn lookup_or_new(
66 context: &Context,
67 namespace: Namespace,
68 foreign_key: Option<&str>,
69) -> Result<String> {
70 if let Some(token) = lookup(context, namespace, foreign_key).await? {
71 return Ok(token);
72 }
73
74 let token = create_id();
75 let timestamp = time();
76 save(context, namespace, foreign_key, &token, timestamp).await?;
77 Ok(token)
78}
79
80pub async fn exists(context: &Context, namespace: Namespace, token: &str) -> Result<bool> {
81 let exists = context
82 .sql
83 .exists(
84 "SELECT COUNT(*) FROM tokens WHERE namespc=? AND token=?;",
85 (namespace, token),
86 )
87 .await?;
88 Ok(exists)
89}
90
91pub async fn delete(context: &Context, foreign_key: &str) -> Result<()> {
96 context
97 .sql
98 .execute("DELETE FROM tokens WHERE foreign_key=?", (foreign_key,))
99 .await?;
100 Ok(())
101}