1#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8pub enum EntityRole {
9 User,
10 Session,
11 Account,
12 Verification,
13}
14
15#[derive(Clone, Copy, Debug)]
16pub struct FieldDef {
17 pub name: &'static str,
18 pub ty: &'static str,
21 pub is_primary_key: bool,
22 pub column_name: Option<&'static str>,
23 pub default_value: Option<&'static str>,
25}
26
27#[derive(Clone, Copy, Debug)]
28pub struct PluginSchema {
29 pub name: &'static str,
30 pub user_fields: &'static [FieldDef],
31 pub session_fields: &'static [FieldDef],
32 pub extra_entities: &'static [ExtraEntitySchema],
33}
34
35#[derive(Clone, Copy, Debug)]
36pub struct ExtraEntitySchema {
37 pub mod_name: &'static str,
38 pub table_name: &'static str,
39 pub role: Option<EntityRole>,
40 pub fields: &'static [FieldDef],
41}
42
43macro_rules! f {
44 ($name:expr, $ty:expr, $default:expr) => {
45 FieldDef {
46 default_value: Some($default),
47 ..f!($name, $ty)
48 }
49 };
50 ($name:expr, $ty:expr) => {
51 FieldDef {
52 name: $name,
53 ty: $ty,
54 is_primary_key: false,
55 column_name: None,
56 default_value: None,
57 }
58 };
59}
60
61macro_rules! pk {
62 ($name:expr, $ty:expr) => {
63 FieldDef {
64 is_primary_key: true,
65 ..f!($name, $ty)
66 }
67 };
68}
69
70macro_rules! f_col {
71 ($name:expr, $ty:expr, $column_name:expr) => {
72 FieldDef {
73 column_name: Some($column_name),
74 ..f!($name, $ty)
75 }
76 };
77}
78
79static USER_CORE: &[FieldDef] = &[
80 pk!("id", "String"),
81 f!("name", "Option<String>"),
82 f!("email", "Option<String>"),
83 f!("email_verified", "bool"),
84 f!("image", "Option<String>"),
85 f!("created_at", "DateTimeUtc"),
86 f!("updated_at", "DateTimeUtc"),
87];
88
89static SESSION_CORE: &[FieldDef] = &[
90 pk!("id", "String"),
91 f!("expires_at", "DateTimeUtc"),
92 f!("token", "String"),
93 f!("created_at", "DateTimeUtc"),
94 f!("updated_at", "DateTimeUtc"),
95 f!("ip_address", "Option<String>"),
96 f!("user_agent", "Option<String>"),
97 f!("user_id", "String"),
98 f!("active", "bool"),
99];
100
101static ACCOUNT_CORE: &[FieldDef] = &[
102 pk!("id", "String"),
103 f!("account_id", "String"),
104 f!("provider_id", "String"),
105 f!("user_id", "String"),
106 f!("access_token", "Option<String>"),
107 f!("refresh_token", "Option<String>"),
108 f!("id_token", "Option<String>"),
109 f!("access_token_expires_at", "Option<DateTimeUtc>"),
110 f!("refresh_token_expires_at", "Option<DateTimeUtc>"),
111 f!("scope", "Option<String>"),
112 f!("password", "Option<String>"),
113 f!("created_at", "DateTimeUtc"),
114 f!("updated_at", "DateTimeUtc"),
115];
116
117static VERIFICATION_CORE: &[FieldDef] = &[
118 pk!("id", "String"),
119 f!("identifier", "String"),
120 f!("value", "String"),
121 f!("expires_at", "DateTimeUtc"),
122 f!("created_at", "DateTimeUtc"),
123 f!("updated_at", "DateTimeUtc"),
124];
125
126static PLUGINS: &[PluginSchema] = &[
127 PluginSchema {
128 name: "siwe",
129 user_fields: &[],
130 session_fields: &[],
131 extra_entities: &[ExtraEntitySchema {
132 mod_name: "wallet_address",
133 table_name: "wallet_address",
134 role: None,
135 fields: &[
136 pk!("id", "String"),
137 f!("user_id", "String"),
138 f!("address", "String"),
139 f!("chain_id", "f64"),
140 f!("is_primary", "bool"),
141 f!("created_at", "DateTimeUtc"),
142 ],
143 }],
144 },
145 PluginSchema {
146 name: "jwt",
147 user_fields: &[],
148 session_fields: &[],
149 extra_entities: &[ExtraEntitySchema {
150 mod_name: "jwk",
151 table_name: "jwks",
152 role: None,
153 fields: &[
154 pk!("id", "String"),
155 f!("public_key", "String"),
156 f!("private_key", "String"),
157 f!("created_at", "DateTimeUtc"),
158 f!("expires_at", "Option<DateTimeUtc>"),
159 f!("alg", "Option<String>"),
160 f!("crv", "Option<String>"),
161 ],
162 }],
163 },
164 PluginSchema {
165 name: "anonymous",
166 user_fields: &[f!("is_anonymous", "Option<bool>")],
167 session_fields: &[],
168 extra_entities: &[],
169 },
170 PluginSchema {
171 name: "phone-number",
172 user_fields: &[
173 f!("phone_number", "Option<String>"),
174 f!("phone_number_verified", "Option<bool>"),
175 ],
176 session_fields: &[],
177 extra_entities: &[],
178 },
179 PluginSchema {
180 name: "last-login-method",
181 user_fields: &[f!("last_login_method", "Option<String>")],
182 session_fields: &[],
183 extra_entities: &[],
184 },
185 PluginSchema {
186 name: "organization-teams",
187 user_fields: &[],
188 session_fields: &[f!("active_team_id", "Option<String>")],
189 extra_entities: &[
190 ExtraEntitySchema {
191 mod_name: "team",
192 table_name: "team",
193 role: None,
194 fields: &[
195 pk!("id", "String"),
196 f!("name", "String"),
197 f!("organization_id", "String"),
198 f!("member_count", "i64"),
199 f!("created_at", "DateTimeUtc"),
200 f!("updated_at", "Option<DateTimeUtc>"),
201 ],
202 },
203 ExtraEntitySchema {
204 mod_name: "team_member",
205 table_name: "team_member",
206 role: None,
207 fields: &[
208 pk!("id", "String"),
209 f!("team_id", "String"),
210 f!("user_id", "String"),
211 f!("membership_key", "Option<String>"),
212 f!("created_at", "DateTimeUtc"),
213 ],
214 },
215 ],
216 },
217 PluginSchema {
218 name: "organization-dynamic-roles",
219 user_fields: &[],
220 session_fields: &[],
221 extra_entities: &[ExtraEntitySchema {
222 mod_name: "organization_role",
223 table_name: "organization_role",
224 role: None,
225 fields: &[
226 pk!("id", "String"),
227 f!("organization_id", "String"),
228 f!("role", "String"),
229 f!("permission", "String"),
230 f!("created_at", "DateTimeUtc"),
231 f!("updated_at", "Option<DateTimeUtc>"),
232 ],
233 }],
234 },
235 PluginSchema {
236 name: "username",
237 user_fields: &[
238 f!("username", "Option<String>"),
239 f!("display_username", "Option<String>"),
240 ],
241 session_fields: &[],
242 extra_entities: &[],
243 },
244 PluginSchema {
245 name: "two-factor",
246 user_fields: &[f!("two_factor_enabled", "Option<bool>")],
247 session_fields: &[],
248 extra_entities: &[ExtraEntitySchema {
249 mod_name: "two_factor",
250 table_name: "two_factor",
251 role: None,
252 fields: &[
253 pk!("id", "String"),
254 f!("secret", "String"),
255 f!("backup_codes", "String"),
256 f!("user_id", "String"),
257 f!("verified", "Option<bool>"),
258 f!("failed_verification_count", "Option<f64>"),
259 f!("locked_until", "Option<DateTimeUtc>"),
260 f!("created_at", "DateTimeUtc"),
261 f!("updated_at", "DateTimeUtc"),
262 ],
263 }],
264 },
265 PluginSchema {
266 name: "device-authorization",
267 user_fields: &[],
268 session_fields: &[],
269 extra_entities: &[ExtraEntitySchema {
270 mod_name: "device_code",
271 table_name: "device_code",
272 role: None,
273 fields: &[
274 pk!("id", "String"),
275 f!("device_code", "String"),
276 f!("user_code", "String"),
277 f!("user_id", "Option<String>"),
278 f!("expires_at", "DateTimeUtc"),
279 f!("status", "String"),
280 f!("last_polled_at", "Option<DateTimeUtc>"),
281 f!("polling_interval", "Option<i64>"),
282 f!("client_id", "Option<String>"),
283 f!("scope", "Option<String>"),
284 ],
285 }],
286 },
287 PluginSchema {
288 name: "admin",
289 user_fields: &[
290 f!("role", "Option<String>"),
291 f!("banned", "Option<bool>"),
292 f!("ban_reason", "Option<String>"),
293 f!("ban_expires", "Option<DateTimeUtc>"),
294 f!("metadata", "Json"),
295 ],
296 session_fields: &[f!("impersonated_by", "Option<String>")],
297 extra_entities: &[],
298 },
299 PluginSchema {
300 name: "organization",
301 user_fields: &[],
302 session_fields: &[f!("active_organization_id", "Option<String>")],
303 extra_entities: &[
304 ExtraEntitySchema {
305 mod_name: "organization",
306 table_name: "organization",
307 role: None,
308 fields: &[
309 pk!("id", "String"),
310 f!("name", "String"),
311 f!("slug", "String"),
312 f!("logo", "Option<String>"),
313 f!("metadata", "Option<Json>"),
314 f!("created_at", "DateTimeUtc"),
315 f!("updated_at", "DateTimeUtc"),
316 ],
317 },
318 ExtraEntitySchema {
319 mod_name: "member",
320 table_name: "member",
321 role: None,
322 fields: &[
323 pk!("id", "String"),
324 f!("organization_id", "String"),
325 f!("user_id", "String"),
326 f!("role", "String"),
327 f!("created_at", "DateTimeUtc"),
328 ],
329 },
330 ExtraEntitySchema {
331 mod_name: "invitation",
332 table_name: "invitation",
333 role: None,
334 fields: &[
335 pk!("id", "String"),
336 f!("organization_id", "String"),
337 f!("email", "String"),
338 f!("role", "String"),
339 f!("team_id", "Option<String>"),
340 f!("status", "String"),
341 f!("inviter_id", "String"),
342 f!("expires_at", "DateTimeUtc"),
343 f!("created_at", "DateTimeUtc"),
344 ],
345 },
346 ],
347 },
348 PluginSchema {
349 name: "api-key",
350 user_fields: &[],
351 session_fields: &[],
352 extra_entities: &[ExtraEntitySchema {
353 mod_name: "api_key",
354 table_name: "api_keys",
355 role: None,
356 fields: &[
357 pk!("id", "String"),
358 f!("name", "Option<String>"),
359 f!("start", "Option<String>"),
360 f!("prefix", "Option<String>"),
361 f_col!("key_hash", "String", "key"),
362 f!("reference_id", "String"),
363 f!("config_id", "String", "default"),
364 f!("refill_interval", "Option<f64>"),
365 f!("refill_amount", "Option<f64>"),
366 f!("last_refill_at", "Option<DateTimeUtc>"),
367 f!("enabled", "bool"),
368 f!("rate_limit_enabled", "bool"),
369 f!("rate_limit_time_window", "Option<f64>"),
370 f!("rate_limit_max", "Option<f64>"),
371 f!("request_count", "Option<f64>"),
372 f!("remaining", "Option<f64>"),
373 f!("last_request", "Option<DateTimeUtc>"),
374 f!("expires_at", "Option<DateTimeUtc>"),
375 f!("created_at", "DateTimeUtc"),
376 f!("updated_at", "DateTimeUtc"),
377 f!("permissions", "Option<String>"),
378 f!("metadata", "Option<String>"),
379 ],
380 }],
381 },
382 PluginSchema {
383 name: "passkey",
384 user_fields: &[],
385 session_fields: &[],
386 extra_entities: &[ExtraEntitySchema {
387 mod_name: "passkey",
388 table_name: "passkeys",
389 role: None,
390 fields: &[
391 pk!("id", "String"),
392 f!("name", "Option<String>"),
393 f!("public_key", "String"),
394 f!("user_id", "String"),
395 f!("credential_id", "String"),
396 f!("counter", "i64"),
397 f!("device_type", "String"),
398 f!("backed_up", "bool"),
399 f!("transports", "Option<String>"),
400 f!("credential", "String"),
401 f!("aaguid", "Option<String>"),
402 f!("created_at", "DateTimeUtc"),
403 f!("updated_at", "DateTimeUtc"),
404 ],
405 }],
406 },
407];
408
409#[must_use]
411pub fn core_fields(role: EntityRole) -> &'static [FieldDef] {
412 match role {
413 EntityRole::User => USER_CORE,
414 EntityRole::Session => SESSION_CORE,
415 EntityRole::Account => ACCOUNT_CORE,
416 EntityRole::Verification => VERIFICATION_CORE,
417 }
418}
419
420#[must_use]
422pub fn plugin_schemas() -> &'static [PluginSchema] {
423 PLUGINS
424}
425
426#[must_use]
428pub fn plugin_field_names(role: EntityRole) -> Vec<&'static str> {
429 plugin_schemas()
430 .iter()
431 .flat_map(|p| match role {
432 EntityRole::User => p.user_fields.iter(),
433 EntityRole::Session => p.session_fields.iter(),
434 EntityRole::Account | EntityRole::Verification => [].iter(),
435 })
436 .map(|f| f.name)
437 .collect()
438}
439
440#[must_use]
442pub fn core_field_names(role: EntityRole) -> Vec<&'static str> {
443 core_fields(role).iter().map(|f| f.name).collect()
444}