database
: Create auth db model
This commit is contained in:
parent
7b7fea9666
commit
64da830ba1
7 changed files with 480 additions and 57 deletions
|
@ -10,7 +10,7 @@ keywords = ["fediverse", "diesel", "database", "postgresql", "database-migration
|
|||
categories = ["database"]
|
||||
|
||||
[dependencies]
|
||||
diesel = { version = "2.2.4", features = ["postgres", "uuid"] }
|
||||
diesel = { version = "2.2.4", features = ["chrono", "postgres", "serde_json", "uuid"] }
|
||||
diesel-async = { version = "0.5.1", features = ["postgres"] }
|
||||
diesel_migrations = { version = "2.2.0", optional = true }
|
||||
log = { version = "0.4.22", features = ["std", "max_level_trace", "release_max_level_debug"] }
|
||||
|
@ -20,6 +20,10 @@ mime = "0.3.17"
|
|||
pretty_env_logger = { version = "0.5.0", optional = true }
|
||||
uuid = "1.11.0"
|
||||
tokio = { version = "1.42.0", optional = true }
|
||||
chrono = "0.4.39"
|
||||
webauthn-rs = { version = "0.5.1", features = ["danger-allow-state-serialisation"] }
|
||||
serde = "1.0.217"
|
||||
serde_json = "1.0.138"
|
||||
|
||||
[features]
|
||||
default = ["connect"]
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
DROP TABLE IF EXISTS auth_authentication CASCADE;
|
||||
DROP TABLE IF EXISTS auth_registration CASCADE;
|
||||
DROP TABLE IF EXISTS auth_passkeys CASCADE;
|
||||
DROP TABLE IF EXISTS auth_users CASCADE;
|
|
@ -1,4 +1,4 @@
|
|||
CREATE TABLE users (
|
||||
CREATE TABLE auth_users (
|
||||
id UUID DEFAULT gen_random_uuid() NOT NULL,
|
||||
username VARCHAR NOT NULL,
|
||||
display_name VARCHAR NOT NULL,
|
||||
|
@ -7,18 +7,18 @@ CREATE TABLE users (
|
|||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE users_passkeys (
|
||||
user_id UUID REFERENCES users (id) NOT NULL,
|
||||
CREATE TABLE auth_passkeys (
|
||||
user_id UUID REFERENCES auth_users (id) NOT NULL,
|
||||
id UUID NOT NULL,
|
||||
|
||||
passkey BYTEA NOT NULL,
|
||||
passkey JSONB NOT NULL,
|
||||
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE users_passkey_registration_state (
|
||||
user_id UUID REFERENCES users (id) NOT NULL,
|
||||
state BYTEA NOT NULL,
|
||||
CREATE TABLE auth_registration (
|
||||
user_id UUID REFERENCES auth_users (id) NOT NULL,
|
||||
state JSONB NOT NULL,
|
||||
|
||||
id UUID DEFAULT gen_random_uuid() NOT NULL,
|
||||
created TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
|
||||
|
@ -26,13 +26,12 @@ CREATE TABLE users_passkey_registration_state (
|
|||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE users_passkey_authentication_state (
|
||||
user_id UUID REFERENCES users (id) NOT NULL,
|
||||
state BYTEA NOT NULL,
|
||||
CREATE TABLE auth_authentication (
|
||||
user_id UUID REFERENCES auth_users (id) NOT NULL,
|
||||
state JSONB NOT NULL,
|
||||
|
||||
id UUID DEFAULT gen_random_uuid() NOT NULL,
|
||||
created TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
|
||||
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
DROP TABLE IF EXISTS users_passkey_authentication_state CASCADE;
|
||||
DROP TABLE IF EXISTS users_passkey_registration_state CASCADE;
|
||||
DROP TABLE IF EXISTS users_passkeys CASCADE;
|
||||
DROP TABLE IF EXISTS users CASCADE;
|
419
acrate_database/src/auth.rs
Normal file
419
acrate_database/src/auth.rs
Normal file
|
@ -0,0 +1,419 @@
|
|||
use chrono::{DateTime, Local};
|
||||
use diesel::deserialize::FromSql;
|
||||
use diesel::{AsExpression, FromSqlRow, Identifiable, Insertable, Queryable, QueryableByName, Selectable, ExpressionMethods, PgConnection, QueryResult, SelectableHelper, OptionalExtension};
|
||||
use diesel::pg::{Pg};
|
||||
use diesel::serialize::{Output, ToSql};
|
||||
use diesel_async::{AsyncPgConnection};
|
||||
use uuid::Uuid;
|
||||
use webauthn_rs::prelude::{AuthenticationState, Passkey, PasskeyRegistration};
|
||||
use crate::schema;
|
||||
use crate::impl_to_insert;
|
||||
|
||||
/// Wrapper to use [`Passkey`] with [`diesel`].
|
||||
#[derive(Debug, Clone, FromSqlRow, AsExpression)]
|
||||
#[diesel(sql_type = diesel::pg::sql_types::Jsonb)]
|
||||
pub struct PasskeyDatabase(serde_json::Value);
|
||||
|
||||
/// Wrapper to use [`PasskeyRegistration`] with [`diesel`].
|
||||
#[derive(Debug, Clone, FromSqlRow, AsExpression)]
|
||||
#[diesel(sql_type = diesel::pg::sql_types::Jsonb)]
|
||||
pub struct PasskeyRegistrationDatabase(serde_json::Value);
|
||||
|
||||
/// Wrapper to use [`AuthenticationState`] with [`diesel`].
|
||||
#[derive(Debug, Clone, FromSqlRow, AsExpression)]
|
||||
#[diesel(sql_type = diesel::pg::sql_types::Jsonb)]
|
||||
pub struct AuthenticationStateDatabase(serde_json::Value);
|
||||
|
||||
|
||||
/// An user.
|
||||
#[derive(Debug, Queryable, QueryableByName, Identifiable, Selectable)]
|
||||
#[diesel(table_name = schema::auth_users)]
|
||||
#[diesel(check_for_backend(Pg))]
|
||||
pub struct AuthUser {
|
||||
/// The identity column of the record.
|
||||
pub id: Uuid,
|
||||
|
||||
/// The user's username, which should be hard to change.
|
||||
pub username: String,
|
||||
|
||||
/// The user's display name, which can be changed at any time.
|
||||
pub display_name: String,
|
||||
}
|
||||
|
||||
/// An [`Insertable`] version of [`AuthUser`].
|
||||
#[derive(Debug, Insertable)]
|
||||
#[diesel(table_name = schema::auth_users)]
|
||||
#[diesel(check_for_backend(Pg))]
|
||||
pub struct AuthUserInsert {
|
||||
/// The user's username, which should be hard to change.
|
||||
pub username: String,
|
||||
|
||||
/// The user's display name, which can be changed at any time.
|
||||
pub display_name: String,
|
||||
}
|
||||
|
||||
/// An user's passkey.
|
||||
#[derive(Debug, Queryable, QueryableByName, Identifiable, Selectable)]
|
||||
#[diesel(table_name = schema::auth_passkeys)]
|
||||
#[diesel(check_for_backend(Pg))]
|
||||
pub struct AuthPasskey {
|
||||
/// The identity column of the record.
|
||||
pub id: Uuid,
|
||||
|
||||
/// The [`AuthUser::id`] this record refers to.
|
||||
pub user_id: Uuid,
|
||||
|
||||
/// The data of the passkey itself.
|
||||
pub passkey: PasskeyDatabase,
|
||||
}
|
||||
|
||||
/// An [`Insertable`] version of [`AuthPasskey`].
|
||||
#[derive(Debug, Insertable)]
|
||||
#[diesel(table_name = schema::auth_passkeys)]
|
||||
#[diesel(check_for_backend(Pg))]
|
||||
pub struct AuthPasskeyInsert {
|
||||
/// The [`AuthUser::id`] this record refers to.
|
||||
pub user_id: Uuid,
|
||||
|
||||
/// The data of the passkey itself.
|
||||
pub passkey: PasskeyDatabase,
|
||||
}
|
||||
|
||||
/// An in-progress passkey registration.
|
||||
#[derive(Debug, Queryable, QueryableByName, Identifiable, Selectable)]
|
||||
#[diesel(belongs_to(AuthUser))]
|
||||
#[diesel(table_name = schema::auth_registration)]
|
||||
#[diesel(check_for_backend(Pg))]
|
||||
pub struct AuthRegistration {
|
||||
/// The [`AuthUser::id`] this record refers to.
|
||||
pub user_id: Uuid,
|
||||
|
||||
/// The binary data of the in-progress registration.
|
||||
pub state: PasskeyRegistrationDatabase,
|
||||
|
||||
/// The identity column of the record.
|
||||
pub id: Uuid,
|
||||
|
||||
/// The moment when this procedure was started.
|
||||
pub created: DateTime<Local>
|
||||
}
|
||||
|
||||
/// An [`Insertable`] version of [`AuthRegistration`].
|
||||
#[derive(Debug, Insertable)]
|
||||
#[diesel(table_name = schema::auth_registration)]
|
||||
#[diesel(check_for_backend(Pg))]
|
||||
pub struct AuthRegistrationInsert {
|
||||
/// The [`AuthUser::id`] this record refers to.
|
||||
pub user_id: Uuid,
|
||||
|
||||
/// The binary data of the in-progress registration.
|
||||
pub state: PasskeyRegistrationDatabase,
|
||||
}
|
||||
|
||||
/// An in-progress passkey authentication.
|
||||
#[derive(Debug, Queryable, QueryableByName, Identifiable, Selectable)]
|
||||
#[diesel(belongs_to(AuthUser))]
|
||||
#[diesel(table_name = schema::auth_authentication)]
|
||||
#[diesel(check_for_backend(Pg))]
|
||||
pub struct AuthAuthentication {
|
||||
/// The [`AuthUser::id`] this record refers to.
|
||||
pub user_id: Uuid,
|
||||
|
||||
/// The binary data of the in-progress authentication.
|
||||
pub state: AuthenticationStateDatabase,
|
||||
|
||||
/// The identity column of the record.
|
||||
pub id: Uuid,
|
||||
|
||||
/// The moment when this procedure was started.
|
||||
pub created: DateTime<Local>
|
||||
}
|
||||
|
||||
/// An [`Insertable`] version of [`AuthAuthentication`].
|
||||
#[derive(Debug, Insertable)]
|
||||
#[diesel(table_name = schema::auth_authentication)]
|
||||
#[diesel(check_for_backend(Pg))]
|
||||
pub struct AuthAuthenticationInsert {
|
||||
/// The [`AuthUser::id`] this record refers to.
|
||||
pub user_id: Uuid,
|
||||
|
||||
/// The binary data of the in-progress authentication.
|
||||
pub state: AuthenticationStateDatabase,
|
||||
}
|
||||
|
||||
|
||||
impl TryFrom<Passkey> for PasskeyDatabase {
|
||||
type Error = serde_json::Error;
|
||||
|
||||
fn try_from(value: Passkey) -> Result<Self, Self::Error> {
|
||||
Ok(Self(
|
||||
serde_json::to_value(value)?
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<PasskeyDatabase> for Passkey {
|
||||
type Error = serde_json::Error;
|
||||
|
||||
fn try_from(value: PasskeyDatabase) -> Result<Self, Self::Error> {
|
||||
serde_json::from_value(value.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Allow [`diesel::pg::sql_types::Jsonb`] values to be parsed as [`PasskeyDatabase`].
|
||||
impl FromSql<diesel::pg::sql_types::Jsonb, Pg> for PasskeyDatabase
|
||||
where
|
||||
serde_json::Value: FromSql<diesel::pg::sql_types::Jsonb, Pg>,
|
||||
{
|
||||
fn from_sql(bytes: <Pg as diesel::backend::Backend>::RawValue<'_>) -> diesel::deserialize::Result<Self> {
|
||||
let v = <serde_json::Value as FromSql<diesel::pg::sql_types::Jsonb, Pg>>::from_sql(bytes)?;
|
||||
|
||||
Ok(Self(v))
|
||||
}
|
||||
}
|
||||
|
||||
/// Allow [`diesel::pg::sql_types::Jsonb`] values to be written to with [`PasskeyDatabase`].
|
||||
impl ToSql<diesel::pg::sql_types::Jsonb, Pg> for PasskeyDatabase
|
||||
where
|
||||
serde_json::Value: ToSql<diesel::pg::sql_types::Jsonb, Pg>,
|
||||
{
|
||||
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> diesel::serialize::Result {
|
||||
<serde_json::Value as ToSql<diesel::pg::sql_types::Jsonb, Pg>>::to_sql(&self.0, out)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl TryFrom<PasskeyRegistration> for PasskeyRegistrationDatabase {
|
||||
type Error = serde_json::Error;
|
||||
|
||||
fn try_from(value: PasskeyRegistration) -> Result<Self, Self::Error> {
|
||||
Ok(Self(
|
||||
serde_json::to_value(value)?
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<PasskeyRegistrationDatabase> for PasskeyRegistration {
|
||||
type Error = serde_json::Error;
|
||||
|
||||
fn try_from(value: PasskeyRegistrationDatabase) -> Result<Self, Self::Error> {
|
||||
serde_json::from_value(value.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Allow [`diesel::pg::sql_types::Jsonb`] values to be parsed as [`PasskeyRegistrationDatabase`].
|
||||
impl FromSql<diesel::pg::sql_types::Jsonb, Pg> for PasskeyRegistrationDatabase
|
||||
where
|
||||
serde_json::Value: FromSql<diesel::pg::sql_types::Jsonb, Pg>,
|
||||
{
|
||||
fn from_sql(bytes: <Pg as diesel::backend::Backend>::RawValue<'_>) -> diesel::deserialize::Result<Self> {
|
||||
let v = <serde_json::Value as FromSql<diesel::pg::sql_types::Jsonb, Pg>>::from_sql(bytes)?;
|
||||
|
||||
Ok(Self(v))
|
||||
}
|
||||
}
|
||||
|
||||
/// Allow [`diesel::pg::sql_types::Jsonb`] values to be written to with [`PasskeyRegistrationDatabase`].
|
||||
impl ToSql<diesel::pg::sql_types::Jsonb, Pg> for PasskeyRegistrationDatabase
|
||||
where
|
||||
serde_json::Value: ToSql<diesel::pg::sql_types::Jsonb, Pg>,
|
||||
{
|
||||
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> diesel::serialize::Result {
|
||||
<serde_json::Value as ToSql<diesel::pg::sql_types::Jsonb, Pg>>::to_sql(&self.0, out)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl TryFrom<AuthenticationState> for AuthenticationStateDatabase {
|
||||
type Error = serde_json::Error;
|
||||
|
||||
fn try_from(value: AuthenticationState) -> Result<Self, Self::Error> {
|
||||
Ok(Self(
|
||||
serde_json::to_value(value)?
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<AuthenticationStateDatabase> for AuthenticationState {
|
||||
type Error = serde_json::Error;
|
||||
|
||||
fn try_from(value: AuthenticationStateDatabase) -> Result<Self, Self::Error> {
|
||||
serde_json::from_value(value.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Allow [`diesel::pg::sql_types::Jsonb`] values to be parsed as [`AuthenticationStateDatabase`].
|
||||
impl FromSql<diesel::pg::sql_types::Jsonb, Pg> for AuthenticationStateDatabase
|
||||
where
|
||||
serde_json::Value: FromSql<diesel::pg::sql_types::Jsonb, Pg>,
|
||||
{
|
||||
fn from_sql(bytes: <Pg as diesel::backend::Backend>::RawValue<'_>) -> diesel::deserialize::Result<Self> {
|
||||
let v = <serde_json::Value as FromSql<diesel::pg::sql_types::Jsonb, Pg>>::from_sql(bytes)?;
|
||||
|
||||
Ok(Self(v))
|
||||
}
|
||||
}
|
||||
|
||||
/// Allow [`diesel::pg::sql_types::Jsonb`] values to be written to with [`AuthenticationStateDatabase`].
|
||||
impl ToSql<diesel::pg::sql_types::Jsonb, Pg> for AuthenticationStateDatabase
|
||||
where
|
||||
serde_json::Value: ToSql<diesel::pg::sql_types::Jsonb, Pg>,
|
||||
{
|
||||
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> diesel::serialize::Result {
|
||||
<serde_json::Value as ToSql<diesel::pg::sql_types::Jsonb, Pg>>::to_sql(&self.0, out)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl AuthUser {
|
||||
/// Synchronously get the user with the specified id.
|
||||
pub fn query_id(conn: &mut PgConnection, user_id: Uuid) -> QueryResult<Option<Self>> {
|
||||
use diesel::QueryDsl;
|
||||
use diesel::RunQueryDsl;
|
||||
use schema::auth_users::dsl::*;
|
||||
|
||||
auth_users
|
||||
.find(user_id)
|
||||
.select(Self::as_select())
|
||||
.get_result(conn)
|
||||
.optional()
|
||||
}
|
||||
|
||||
/// Asynchronously get the user with the specified id.
|
||||
pub async fn aquery_id(conn: &mut AsyncPgConnection, user_id: Uuid) -> QueryResult<Option<Self>> {
|
||||
use diesel::QueryDsl;
|
||||
use diesel_async::RunQueryDsl;
|
||||
use schema::auth_users::dsl::*;
|
||||
|
||||
auth_users
|
||||
.find(user_id)
|
||||
.select(Self::as_select())
|
||||
.get_result(conn)
|
||||
.await
|
||||
.optional()
|
||||
}
|
||||
|
||||
/// Synchronously get the user with the specified username.
|
||||
pub fn query_username(conn: &mut PgConnection, user_name: &str) -> QueryResult<Option<Self>> {
|
||||
use diesel::QueryDsl;
|
||||
use diesel::RunQueryDsl;
|
||||
use schema::auth_users::dsl::*;
|
||||
|
||||
let matching_username = username.eq(user_name);
|
||||
|
||||
auth_users
|
||||
.filter(matching_username)
|
||||
.select(Self::as_select())
|
||||
.get_result(conn)
|
||||
.optional()
|
||||
}
|
||||
|
||||
/// Asynchronously get the user with the specified username.
|
||||
pub async fn aquery_username(conn: &mut AsyncPgConnection, user_name: &str) -> QueryResult<Option<Self>> {
|
||||
use diesel::QueryDsl;
|
||||
use diesel_async::RunQueryDsl;
|
||||
use schema::auth_users::dsl::*;
|
||||
|
||||
let matching_username = username.eq(user_name);
|
||||
|
||||
auth_users
|
||||
.filter(matching_username)
|
||||
.select(Self::as_select())
|
||||
.get_result(conn)
|
||||
.await
|
||||
.optional()
|
||||
}
|
||||
}
|
||||
|
||||
impl AuthPasskey {
|
||||
/// Synchronously get the passkey with the specified id.
|
||||
pub fn query_id(conn: &mut PgConnection, passkey_id: Uuid) -> QueryResult<Option<Self>> {
|
||||
use diesel::QueryDsl;
|
||||
use diesel::RunQueryDsl;
|
||||
use schema::auth_passkeys::dsl::*;
|
||||
|
||||
auth_passkeys
|
||||
.find(passkey_id)
|
||||
.select(Self::as_select())
|
||||
.get_result(conn)
|
||||
.optional()
|
||||
}
|
||||
|
||||
/// Asynchronously get the passkey with the specified id.
|
||||
pub async fn aquery_id(conn: &mut AsyncPgConnection, passkey_id: Uuid) -> QueryResult<Option<Self>> {
|
||||
use diesel::QueryDsl;
|
||||
use diesel_async::RunQueryDsl;
|
||||
use schema::auth_passkeys::dsl::*;
|
||||
|
||||
auth_passkeys
|
||||
.find(passkey_id)
|
||||
.select(Self::as_select())
|
||||
.get_result(conn)
|
||||
.await
|
||||
.optional()
|
||||
}
|
||||
}
|
||||
|
||||
impl AuthRegistration {
|
||||
/// Synchronously get the registration with the specified id.
|
||||
pub fn query_id(conn: &mut PgConnection, registration_id: Uuid) -> QueryResult<Option<Self>> {
|
||||
use diesel::QueryDsl;
|
||||
use diesel::RunQueryDsl;
|
||||
use schema::auth_registration::dsl::*;
|
||||
|
||||
auth_registration
|
||||
.find(registration_id)
|
||||
.select(Self::as_select())
|
||||
.get_result(conn)
|
||||
.optional()
|
||||
}
|
||||
|
||||
/// Asynchronously get the registration with the specified id.
|
||||
pub async fn aquery_id(conn: &mut AsyncPgConnection, registration_id: Uuid) -> QueryResult<Option<Self>> {
|
||||
use diesel::QueryDsl;
|
||||
use diesel_async::RunQueryDsl;
|
||||
use schema::auth_registration::dsl::*;
|
||||
|
||||
auth_registration
|
||||
.find(registration_id)
|
||||
.select(Self::as_select())
|
||||
.get_result(conn)
|
||||
.await
|
||||
.optional()
|
||||
}
|
||||
}
|
||||
|
||||
impl AuthAuthentication {
|
||||
/// Synchronously get the authentication with the specified id.
|
||||
pub fn query_id(conn: &mut PgConnection, authentication_id: Uuid) -> QueryResult<Option<Self>> {
|
||||
use diesel::QueryDsl;
|
||||
use diesel::RunQueryDsl;
|
||||
use schema::auth_authentication::dsl::*;
|
||||
|
||||
auth_authentication
|
||||
.find(authentication_id)
|
||||
.select(Self::as_select())
|
||||
.get_result(conn)
|
||||
.optional()
|
||||
}
|
||||
|
||||
/// Asynchronously get the authentication with the specified id.
|
||||
pub async fn aquery_id(conn: &mut AsyncPgConnection, authentication_id: Uuid) -> QueryResult<Option<Self>> {
|
||||
use diesel::QueryDsl;
|
||||
use diesel_async::RunQueryDsl;
|
||||
use schema::auth_authentication::dsl::*;
|
||||
|
||||
auth_authentication
|
||||
.find(authentication_id)
|
||||
.select(Self::as_select())
|
||||
.get_result(conn)
|
||||
.await
|
||||
.optional()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl_to_insert!(AuthUserInsert => AuthUser: schema::auth_users::table);
|
||||
impl_to_insert!(AuthPasskeyInsert => AuthPasskey: schema::auth_passkeys::table);
|
||||
impl_to_insert!(AuthRegistrationInsert => AuthRegistration: schema::auth_registration::table);
|
||||
impl_to_insert!(AuthAuthenticationInsert => AuthAuthentication: schema::auth_authentication::table);
|
|
@ -8,6 +8,7 @@
|
|||
mod schema;
|
||||
|
||||
pub mod meta;
|
||||
pub mod auth;
|
||||
|
||||
mod macros;
|
||||
|
||||
|
|
|
@ -1,5 +1,39 @@
|
|||
// @generated automatically by Diesel CLI.
|
||||
|
||||
diesel::table! {
|
||||
auth_authentication (id) {
|
||||
user_id -> Uuid,
|
||||
state -> Jsonb,
|
||||
id -> Uuid,
|
||||
created -> Timestamptz,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
auth_passkeys (id) {
|
||||
user_id -> Uuid,
|
||||
id -> Uuid,
|
||||
passkey -> Jsonb,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
auth_registration (id) {
|
||||
user_id -> Uuid,
|
||||
state -> Jsonb,
|
||||
id -> Uuid,
|
||||
created -> Timestamptz,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
auth_users (id) {
|
||||
id -> Uuid,
|
||||
username -> Varchar,
|
||||
display_name -> Varchar,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
meta_aliases (id) {
|
||||
id -> Uuid,
|
||||
|
@ -60,55 +94,21 @@ diesel::table! {
|
|||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
users (id) {
|
||||
id -> Uuid,
|
||||
username -> Varchar,
|
||||
display_name -> Varchar,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
users_passkey_authentication_state (id) {
|
||||
user_id -> Uuid,
|
||||
state -> Bytea,
|
||||
id -> Uuid,
|
||||
created -> Timestamptz,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
users_passkey_registration_state (id) {
|
||||
user_id -> Uuid,
|
||||
state -> Bytea,
|
||||
id -> Uuid,
|
||||
created -> Timestamptz,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
users_passkeys (id) {
|
||||
user_id -> Uuid,
|
||||
id -> Uuid,
|
||||
passkey -> Bytea,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::joinable!(auth_authentication -> auth_users (user_id));
|
||||
diesel::joinable!(auth_passkeys -> auth_users (user_id));
|
||||
diesel::joinable!(auth_registration -> auth_users (user_id));
|
||||
diesel::joinable!(meta_link_properties -> meta_links (meta_link_id));
|
||||
diesel::joinable!(meta_link_titles -> meta_links (meta_link_id));
|
||||
diesel::joinable!(users_passkey_authentication_state -> users (user_id));
|
||||
diesel::joinable!(users_passkey_registration_state -> users (user_id));
|
||||
diesel::joinable!(users_passkeys -> users (user_id));
|
||||
|
||||
diesel::allow_tables_to_appear_in_same_query!(
|
||||
auth_authentication,
|
||||
auth_passkeys,
|
||||
auth_registration,
|
||||
auth_users,
|
||||
meta_aliases,
|
||||
meta_link_properties,
|
||||
meta_link_titles,
|
||||
meta_links,
|
||||
meta_properties,
|
||||
meta_subjects,
|
||||
users,
|
||||
users_passkey_authentication_state,
|
||||
users_passkey_registration_state,
|
||||
users_passkeys,
|
||||
);
|
||||
|
|
Loading…
Add table
Reference in a new issue