1use chrono::{DateTime, Utc};
7use mas_data_model::{
8 BrowserSession, CompatSession, Device, Session, User, UserEmailAuthentication,
9 UserRecoverySession,
10};
11use serde::{Deserialize, Serialize};
12use ulid::Ulid;
13
14use super::InsertableJob;
15use crate::{Page, Pagination};
16
17#[derive(Serialize, Deserialize, Debug, Clone)]
21pub struct VerifyEmailJob {
22 user_email_id: Ulid,
23 language: Option<String>,
24}
25
26impl VerifyEmailJob {
27 #[must_use]
29 pub fn user_email_id(&self) -> Ulid {
30 self.user_email_id
31 }
32}
33
34impl InsertableJob for VerifyEmailJob {
35 const QUEUE_NAME: &'static str = "verify-email";
36}
37
38#[derive(Serialize, Deserialize, Debug, Clone)]
40pub struct SendEmailAuthenticationCodeJob {
41 user_email_authentication_id: Ulid,
42 language: String,
43}
44
45impl SendEmailAuthenticationCodeJob {
46 #[must_use]
48 pub fn new(user_email_authentication: &UserEmailAuthentication, language: String) -> Self {
49 Self {
50 user_email_authentication_id: user_email_authentication.id,
51 language,
52 }
53 }
54
55 #[must_use]
57 pub fn language(&self) -> &str {
58 &self.language
59 }
60
61 #[must_use]
63 pub fn user_email_authentication_id(&self) -> Ulid {
64 self.user_email_authentication_id
65 }
66}
67
68impl InsertableJob for SendEmailAuthenticationCodeJob {
69 const QUEUE_NAME: &'static str = "send-email-authentication-code";
70}
71
72#[derive(Serialize, Deserialize, Debug, Clone)]
74pub struct ProvisionUserJob {
75 user_id: Ulid,
76 set_display_name: Option<String>,
77}
78
79impl ProvisionUserJob {
80 #[must_use]
82 pub fn new(user: &User) -> Self {
83 Self {
84 user_id: user.id,
85 set_display_name: None,
86 }
87 }
88
89 #[doc(hidden)]
90 #[must_use]
91 pub fn new_for_id(user_id: Ulid) -> Self {
92 Self {
93 user_id,
94 set_display_name: None,
95 }
96 }
97
98 #[must_use]
100 pub fn set_display_name(mut self, display_name: String) -> Self {
101 self.set_display_name = Some(display_name);
102 self
103 }
104
105 #[must_use]
107 pub fn display_name_to_set(&self) -> Option<&str> {
108 self.set_display_name.as_deref()
109 }
110
111 #[must_use]
113 pub fn user_id(&self) -> Ulid {
114 self.user_id
115 }
116}
117
118impl InsertableJob for ProvisionUserJob {
119 const QUEUE_NAME: &'static str = "provision-user";
120}
121
122#[derive(Serialize, Deserialize, Debug, Clone)]
127pub struct ProvisionDeviceJob {
128 user_id: Ulid,
129 device_id: String,
130}
131
132impl ProvisionDeviceJob {
133 #[must_use]
135 pub fn user_id(&self) -> Ulid {
136 self.user_id
137 }
138
139 #[must_use]
141 pub fn device_id(&self) -> &str {
142 &self.device_id
143 }
144}
145
146impl InsertableJob for ProvisionDeviceJob {
147 const QUEUE_NAME: &'static str = "provision-device";
148}
149
150#[derive(Serialize, Deserialize, Debug, Clone)]
155pub struct DeleteDeviceJob {
156 user_id: Ulid,
157 device_id: String,
158}
159
160impl DeleteDeviceJob {
161 #[must_use]
163 pub fn new(user: &User, device: &Device) -> Self {
164 Self {
165 user_id: user.id,
166 device_id: device.as_str().to_owned(),
167 }
168 }
169
170 #[must_use]
172 pub fn user_id(&self) -> Ulid {
173 self.user_id
174 }
175
176 #[must_use]
178 pub fn device_id(&self) -> &str {
179 &self.device_id
180 }
181}
182
183impl InsertableJob for DeleteDeviceJob {
184 const QUEUE_NAME: &'static str = "delete-device";
185}
186
187#[derive(Serialize, Deserialize, Debug, Clone)]
189pub struct SyncDevicesJob {
190 user_id: Ulid,
191}
192
193impl SyncDevicesJob {
194 #[must_use]
197 pub fn new(user: &User) -> Self {
198 Self { user_id: user.id }
199 }
200
201 #[must_use]
206 pub fn new_for_id(user_id: Ulid) -> Self {
207 Self { user_id }
208 }
209
210 #[must_use]
212 pub fn user_id(&self) -> Ulid {
213 self.user_id
214 }
215}
216
217impl InsertableJob for SyncDevicesJob {
218 const QUEUE_NAME: &'static str = "sync-devices";
219}
220
221#[derive(Serialize, Deserialize, Debug, Clone)]
223pub struct DeactivateUserJob {
224 user_id: Ulid,
225 hs_erase: bool,
226}
227
228impl DeactivateUserJob {
229 #[must_use]
236 pub fn new(user: &User, hs_erase: bool) -> Self {
237 Self {
238 user_id: user.id,
239 hs_erase,
240 }
241 }
242
243 #[must_use]
245 pub fn user_id(&self) -> Ulid {
246 self.user_id
247 }
248
249 #[must_use]
251 pub fn hs_erase(&self) -> bool {
252 self.hs_erase
253 }
254}
255
256impl InsertableJob for DeactivateUserJob {
257 const QUEUE_NAME: &'static str = "deactivate-user";
258}
259
260#[derive(Serialize, Deserialize, Debug, Clone)]
262pub struct ReactivateUserJob {
263 user_id: Ulid,
264}
265
266impl ReactivateUserJob {
267 #[must_use]
273 pub fn new(user: &User) -> Self {
274 Self { user_id: user.id }
275 }
276
277 #[must_use]
279 pub fn user_id(&self) -> Ulid {
280 self.user_id
281 }
282}
283
284impl InsertableJob for ReactivateUserJob {
285 const QUEUE_NAME: &'static str = "reactivate-user";
286}
287
288#[derive(Serialize, Deserialize, Debug, Clone)]
290pub struct SendAccountRecoveryEmailsJob {
291 user_recovery_session_id: Ulid,
292}
293
294impl SendAccountRecoveryEmailsJob {
295 #[must_use]
303 pub fn new(user_recovery_session: &UserRecoverySession) -> Self {
304 Self {
305 user_recovery_session_id: user_recovery_session.id,
306 }
307 }
308
309 #[must_use]
311 pub fn user_recovery_session_id(&self) -> Ulid {
312 self.user_recovery_session_id
313 }
314}
315
316impl InsertableJob for SendAccountRecoveryEmailsJob {
317 const QUEUE_NAME: &'static str = "send-account-recovery-email";
318}
319
320#[derive(Serialize, Deserialize, Debug, Clone, Default)]
322pub struct CleanupExpiredTokensJob;
323
324impl InsertableJob for CleanupExpiredTokensJob {
325 const QUEUE_NAME: &'static str = "cleanup-expired-tokens";
326}
327
328#[derive(Serialize, Deserialize, Debug, Clone)]
333pub struct ExpireInactiveSessionsJob;
334
335impl InsertableJob for ExpireInactiveSessionsJob {
336 const QUEUE_NAME: &'static str = "expire-inactive-sessions";
337}
338
339#[derive(Serialize, Deserialize, Debug, Clone)]
341pub struct ExpireInactiveOAuthSessionsJob {
342 threshold: DateTime<Utc>,
343 after: Option<Ulid>,
344}
345
346impl ExpireInactiveOAuthSessionsJob {
347 #[must_use]
353 pub fn new(threshold: DateTime<Utc>) -> Self {
354 Self {
355 threshold,
356 after: None,
357 }
358 }
359
360 #[must_use]
362 pub fn threshold(&self) -> DateTime<Utc> {
363 self.threshold
364 }
365
366 #[must_use]
368 pub fn pagination(&self, batch_size: usize) -> Pagination {
369 let pagination = Pagination::first(batch_size);
370 if let Some(after) = self.after {
371 pagination.after(after)
372 } else {
373 pagination
374 }
375 }
376
377 #[must_use]
379 pub fn next(&self, page: &Page<Session>) -> Option<Self> {
380 if !page.has_next_page {
381 return None;
382 }
383
384 let last_edge = page.edges.last()?;
385 Some(Self {
386 threshold: self.threshold,
387 after: Some(last_edge.id),
388 })
389 }
390}
391
392impl InsertableJob for ExpireInactiveOAuthSessionsJob {
393 const QUEUE_NAME: &'static str = "expire-inactive-oauth-sessions";
394}
395
396#[derive(Serialize, Deserialize, Debug, Clone)]
398pub struct ExpireInactiveCompatSessionsJob {
399 threshold: DateTime<Utc>,
400 after: Option<Ulid>,
401}
402
403impl ExpireInactiveCompatSessionsJob {
404 #[must_use]
410 pub fn new(threshold: DateTime<Utc>) -> Self {
411 Self {
412 threshold,
413 after: None,
414 }
415 }
416
417 #[must_use]
419 pub fn threshold(&self) -> DateTime<Utc> {
420 self.threshold
421 }
422
423 #[must_use]
425 pub fn pagination(&self, batch_size: usize) -> Pagination {
426 let pagination = Pagination::first(batch_size);
427 if let Some(after) = self.after {
428 pagination.after(after)
429 } else {
430 pagination
431 }
432 }
433
434 #[must_use]
436 pub fn next(&self, page: &Page<CompatSession>) -> Option<Self> {
437 if !page.has_next_page {
438 return None;
439 }
440
441 let last_edge = page.edges.last()?;
442 Some(Self {
443 threshold: self.threshold,
444 after: Some(last_edge.id),
445 })
446 }
447}
448
449impl InsertableJob for ExpireInactiveCompatSessionsJob {
450 const QUEUE_NAME: &'static str = "expire-inactive-compat-sessions";
451}
452
453#[derive(Debug, Serialize, Deserialize)]
455pub struct ExpireInactiveUserSessionsJob {
456 threshold: DateTime<Utc>,
457 after: Option<Ulid>,
458}
459
460impl ExpireInactiveUserSessionsJob {
461 #[must_use]
467 pub fn new(threshold: DateTime<Utc>) -> Self {
468 Self {
469 threshold,
470 after: None,
471 }
472 }
473
474 #[must_use]
476 pub fn threshold(&self) -> DateTime<Utc> {
477 self.threshold
478 }
479
480 #[must_use]
482 pub fn pagination(&self, batch_size: usize) -> Pagination {
483 let pagination = Pagination::first(batch_size);
484 if let Some(after) = self.after {
485 pagination.after(after)
486 } else {
487 pagination
488 }
489 }
490
491 #[must_use]
493 pub fn next(&self, page: &Page<BrowserSession>) -> Option<Self> {
494 if !page.has_next_page {
495 return None;
496 }
497
498 let last_edge = page.edges.last()?;
499 Some(Self {
500 threshold: self.threshold,
501 after: Some(last_edge.id),
502 })
503 }
504}
505
506impl InsertableJob for ExpireInactiveUserSessionsJob {
507 const QUEUE_NAME: &'static str = "expire-inactive-user-sessions";
508}
509
510#[derive(Debug, Serialize, Deserialize)]
512pub struct PruneStalePolicyDataJob;
513
514impl InsertableJob for PruneStalePolicyDataJob {
515 const QUEUE_NAME: &'static str = "prune-stale-policy-data";
516}