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