Mark database fields as sensitive so they dont show up in logs (#4720)

* Mark database fields as sensitive so they dont show up in logs

* add file

* fix test

* Update crates/apub/src/objects/person.rs

Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com>

* Update crates/apub/src/objects/community.rs

Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com>

* Update crates/apub/src/objects/instance.rs

Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com>

---------

Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com>
Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
This commit is contained in:
Nutomic 2024-05-17 02:41:57 +02:00 committed by GitHub
parent 1a4aa3eaba
commit 99aac07714
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 114 additions and 165 deletions

View File

@ -1,11 +1,7 @@
use crate::{build_totp_2fa, generate_totp_2fa_secret}; use crate::{build_totp_2fa, generate_totp_2fa_secret};
use activitypub_federation::config::Data; use activitypub_federation::config::Data;
use actix_web::web::Json; use actix_web::web::Json;
use lemmy_api_common::{ use lemmy_api_common::{context::LemmyContext, person::GenerateTotpSecretResponse};
context::LemmyContext,
person::GenerateTotpSecretResponse,
sensitive::Sensitive,
};
use lemmy_db_schema::source::local_user::{LocalUser, LocalUserUpdateForm}; use lemmy_db_schema::source::local_user::{LocalUser, LocalUserUpdateForm};
use lemmy_db_views::structs::{LocalUserView, SiteView}; use lemmy_db_views::structs::{LocalUserView, SiteView};
use lemmy_utils::error::{LemmyErrorType, LemmyResult}; use lemmy_utils::error::{LemmyErrorType, LemmyResult};
@ -41,6 +37,6 @@ pub async fn generate_totp_secret(
.await?; .await?;
Ok(Json(GenerateTotpSecretResponse { Ok(Json(GenerateTotpSecretResponse {
totp_secret_url: Sensitive::new(secret_url), totp_secret_url: secret_url.into(),
})) }))
} }

View File

@ -28,6 +28,7 @@ use lemmy_utils::{
error::{LemmyErrorType, LemmyResult}, error::{LemmyErrorType, LemmyResult},
utils::validation::{is_valid_bio_field, is_valid_display_name, is_valid_matrix_id}, utils::validation::{is_valid_bio_field, is_valid_display_name, is_valid_matrix_id},
}; };
use std::ops::Deref;
#[tracing::instrument(skip(context))] #[tracing::instrument(skip(context))]
pub async fn save_user_settings( pub async fn save_user_settings(
@ -57,7 +58,7 @@ pub async fn save_user_settings(
if let Some(Some(email)) = &email { if let Some(Some(email)) = &email {
let previous_email = local_user_view.local_user.email.clone().unwrap_or_default(); let previous_email = local_user_view.local_user.email.clone().unwrap_or_default();
// if email was changed, check that it is not taken and send verification mail // if email was changed, check that it is not taken and send verification mail
if &previous_email != email { if previous_email.deref() != email {
if LocalUser::is_email_taken(&mut context.pool(), email).await? { if LocalUser::is_email_taken(&mut context.pool(), email).await? {
return Err(LemmyErrorType::EmailAlreadyExists)?; return Err(LemmyErrorType::EmailAlreadyExists)?;
} }

View File

@ -1,9 +1,10 @@
use crate::{context::LemmyContext, sensitive::Sensitive}; use crate::context::LemmyContext;
use actix_web::{http::header::USER_AGENT, HttpRequest}; use actix_web::{http::header::USER_AGENT, HttpRequest};
use chrono::Utc; use chrono::Utc;
use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation}; use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};
use lemmy_db_schema::{ use lemmy_db_schema::{
newtypes::LocalUserId, newtypes::LocalUserId,
sensitive::SensitiveString,
source::login_token::{LoginToken, LoginTokenCreateForm}, source::login_token::{LoginToken, LoginTokenCreateForm},
}; };
use lemmy_utils::error::{LemmyErrorExt, LemmyErrorType, LemmyResult}; use lemmy_utils::error::{LemmyErrorExt, LemmyErrorType, LemmyResult};
@ -40,7 +41,7 @@ impl Claims {
user_id: LocalUserId, user_id: LocalUserId,
req: HttpRequest, req: HttpRequest,
context: &LemmyContext, context: &LemmyContext,
) -> LemmyResult<Sensitive<String>> { ) -> LemmyResult<SensitiveString> {
let hostname = context.settings().hostname.clone(); let hostname = context.settings().hostname.clone();
let my_claims = Claims { let my_claims = Claims {
sub: user_id.0.to_string(), sub: user_id.0.to_string(),
@ -50,7 +51,7 @@ impl Claims {
let secret = &context.secret().jwt_secret; let secret = &context.secret().jwt_secret;
let key = EncodingKey::from_secret(secret.as_ref()); let key = EncodingKey::from_secret(secret.as_ref());
let token = encode(&Header::default(), &my_claims, &key)?; let token: SensitiveString = encode(&Header::default(), &my_claims, &key)?.into();
let ip = req let ip = req
.connection_info() .connection_info()
.realip_remote_addr() .realip_remote_addr()
@ -67,7 +68,7 @@ impl Claims {
user_agent, user_agent,
}; };
LoginToken::create(&mut context.pool(), form).await?; LoginToken::create(&mut context.pool(), form).await?;
Ok(Sensitive::new(token)) Ok(token)
} }
} }

View File

@ -64,7 +64,7 @@ impl LemmyContext {
let client = ClientBuilder::new(client).build(); let client = ClientBuilder::new(client).build();
let secret = Secret { let secret = Secret {
id: 0, id: 0,
jwt_secret: String::new(), jwt_secret: String::new().into(),
}; };
let rate_limit_cell = RateLimitCell::with_test_config(); let rate_limit_cell = RateLimitCell::with_test_config();

View File

@ -14,7 +14,6 @@ pub mod private_message;
pub mod request; pub mod request;
#[cfg(feature = "full")] #[cfg(feature = "full")]
pub mod send_activity; pub mod send_activity;
pub mod sensitive;
pub mod site; pub mod site;
#[cfg(feature = "full")] #[cfg(feature = "full")]
pub mod utils; pub mod utils;

View File

@ -1,6 +1,6 @@
use crate::sensitive::Sensitive;
use lemmy_db_schema::{ use lemmy_db_schema::{
newtypes::{CommentReplyId, CommunityId, LanguageId, PersonId, PersonMentionId}, newtypes::{CommentReplyId, CommunityId, LanguageId, PersonId, PersonMentionId},
sensitive::SensitiveString,
source::site::Site, source::site::Site,
CommentSortType, CommentSortType,
ListingType, ListingType,
@ -25,8 +25,8 @@ use ts_rs::TS;
#[cfg_attr(feature = "full", ts(export))] #[cfg_attr(feature = "full", ts(export))]
/// Logging into lemmy. /// Logging into lemmy.
pub struct Login { pub struct Login {
pub username_or_email: Sensitive<String>, pub username_or_email: SensitiveString,
pub password: Sensitive<String>, pub password: SensitiveString,
/// May be required, if totp is enabled for their account. /// May be required, if totp is enabled for their account.
pub totp_2fa_token: Option<String>, pub totp_2fa_token: Option<String>,
} }
@ -38,11 +38,11 @@ pub struct Login {
/// Register / Sign up to lemmy. /// Register / Sign up to lemmy.
pub struct Register { pub struct Register {
pub username: String, pub username: String,
pub password: Sensitive<String>, pub password: SensitiveString,
pub password_verify: Sensitive<String>, pub password_verify: SensitiveString,
pub show_nsfw: Option<bool>, pub show_nsfw: Option<bool>,
/// email is mandatory if email verification is enabled on the server /// email is mandatory if email verification is enabled on the server
pub email: Option<Sensitive<String>>, pub email: Option<SensitiveString>,
/// The UUID of the captcha item. /// The UUID of the captcha item.
pub captcha_uuid: Option<String>, pub captcha_uuid: Option<String>,
/// Your captcha answer. /// Your captcha answer.
@ -99,7 +99,7 @@ pub struct SaveUserSettings {
/// Your display name, which can contain strange characters, and does not need to be unique. /// Your display name, which can contain strange characters, and does not need to be unique.
pub display_name: Option<String>, pub display_name: Option<String>,
/// Your email. /// Your email.
pub email: Option<Sensitive<String>>, pub email: Option<SensitiveString>,
/// Your bio / info, in markdown. /// Your bio / info, in markdown.
pub bio: Option<String>, pub bio: Option<String>,
/// Your matrix user id. Ex: @my_user:matrix.org /// Your matrix user id. Ex: @my_user:matrix.org
@ -140,9 +140,9 @@ pub struct SaveUserSettings {
#[cfg_attr(feature = "full", ts(export))] #[cfg_attr(feature = "full", ts(export))]
/// Changes your account password. /// Changes your account password.
pub struct ChangePassword { pub struct ChangePassword {
pub new_password: Sensitive<String>, pub new_password: SensitiveString,
pub new_password_verify: Sensitive<String>, pub new_password_verify: SensitiveString,
pub old_password: Sensitive<String>, pub old_password: SensitiveString,
} }
#[skip_serializing_none] #[skip_serializing_none]
@ -152,7 +152,7 @@ pub struct ChangePassword {
/// A response for your login. /// A response for your login.
pub struct LoginResponse { pub struct LoginResponse {
/// This is None in response to `Register` if email verification is enabled, or the server requires registration applications. /// This is None in response to `Register` if email verification is enabled, or the server requires registration applications.
pub jwt: Option<Sensitive<String>>, pub jwt: Option<SensitiveString>,
/// If registration applications are required, this will return true for a signup response. /// If registration applications are required, this will return true for a signup response.
pub registration_created: bool, pub registration_created: bool,
/// If email verifications are required, this will return true for a signup response. /// If email verifications are required, this will return true for a signup response.
@ -340,7 +340,7 @@ pub struct CommentReplyResponse {
#[cfg_attr(feature = "full", ts(export))] #[cfg_attr(feature = "full", ts(export))]
/// Delete your account. /// Delete your account.
pub struct DeleteAccount { pub struct DeleteAccount {
pub password: Sensitive<String>, pub password: SensitiveString,
pub delete_content: bool, pub delete_content: bool,
} }
@ -349,7 +349,7 @@ pub struct DeleteAccount {
#[cfg_attr(feature = "full", ts(export))] #[cfg_attr(feature = "full", ts(export))]
/// Reset your password via email. /// Reset your password via email.
pub struct PasswordReset { pub struct PasswordReset {
pub email: Sensitive<String>, pub email: SensitiveString,
} }
#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq, Hash)] #[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq, Hash)]
@ -357,9 +357,9 @@ pub struct PasswordReset {
#[cfg_attr(feature = "full", ts(export))] #[cfg_attr(feature = "full", ts(export))]
/// Change your password after receiving a reset request. /// Change your password after receiving a reset request.
pub struct PasswordChangeAfterReset { pub struct PasswordChangeAfterReset {
pub token: Sensitive<String>, pub token: SensitiveString,
pub password: Sensitive<String>, pub password: SensitiveString,
pub password_verify: Sensitive<String>, pub password_verify: SensitiveString,
} }
#[skip_serializing_none] #[skip_serializing_none]
@ -405,7 +405,7 @@ pub struct VerifyEmail {
#[cfg_attr(feature = "full", derive(TS))] #[cfg_attr(feature = "full", derive(TS))]
#[cfg_attr(feature = "full", ts(export))] #[cfg_attr(feature = "full", ts(export))]
pub struct GenerateTotpSecretResponse { pub struct GenerateTotpSecretResponse {
pub totp_secret_url: Sensitive<String>, pub totp_secret_url: SensitiveString,
} }
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Hash)]

View File

@ -1,116 +0,0 @@
use serde::{Deserialize, Serialize};
use std::{
borrow::Borrow,
ops::{Deref, DerefMut},
};
#[cfg(feature = "full")]
use ts_rs::TS;
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize, Default)]
#[serde(transparent)]
pub struct Sensitive<T>(T);
impl<T> Sensitive<T> {
pub fn new(item: T) -> Self {
Sensitive(item)
}
pub fn into_inner(self) -> T {
self.0
}
}
impl<T> std::fmt::Debug for Sensitive<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Sensitive").finish()
}
}
impl<T> AsRef<T> for Sensitive<T> {
fn as_ref(&self) -> &T {
&self.0
}
}
impl AsRef<str> for Sensitive<String> {
fn as_ref(&self) -> &str {
&self.0
}
}
impl AsRef<[u8]> for Sensitive<String> {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl AsRef<[u8]> for Sensitive<Vec<u8>> {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl<T> AsMut<T> for Sensitive<T> {
fn as_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl AsMut<str> for Sensitive<String> {
fn as_mut(&mut self) -> &mut str {
&mut self.0
}
}
impl Deref for Sensitive<String> {
type Target = str;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Sensitive<String> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T> From<T> for Sensitive<T> {
fn from(t: T) -> Self {
Sensitive(t)
}
}
impl From<&str> for Sensitive<String> {
fn from(s: &str) -> Self {
Sensitive(s.into())
}
}
impl<T> Borrow<T> for Sensitive<T> {
fn borrow(&self) -> &T {
&self.0
}
}
impl Borrow<str> for Sensitive<String> {
fn borrow(&self) -> &str {
&self.0
}
}
#[cfg(feature = "full")]
impl TS for Sensitive<String> {
fn name() -> String {
"string".to_string()
}
fn name_with_type_args(_args: Vec<String>) -> String {
"string".to_string()
}
fn dependencies() -> Vec<ts_rs::Dependency> {
Vec::new()
}
fn transparent() -> bool {
true
}
}

View File

@ -28,6 +28,7 @@ use lemmy_api_common::{
}, },
}; };
use lemmy_db_schema::{ use lemmy_db_schema::{
sensitive::SensitiveString,
source::{ source::{
activity::ActorType, activity::ActorType,
actor_language::CommunityLanguage, actor_language::CommunityLanguage,
@ -213,7 +214,7 @@ impl Actor for ApubCommunity {
} }
fn private_key_pem(&self) -> Option<String> { fn private_key_pem(&self) -> Option<String> {
self.private_key.clone() self.private_key.clone().map(SensitiveString::into_inner)
} }
fn inbox(&self) -> Url { fn inbox(&self) -> Url {

View File

@ -29,6 +29,7 @@ use lemmy_api_common::{
}; };
use lemmy_db_schema::{ use lemmy_db_schema::{
newtypes::InstanceId, newtypes::InstanceId,
sensitive::SensitiveString,
source::{ source::{
activity::ActorType, activity::ActorType,
actor_language::SiteLanguage, actor_language::SiteLanguage,
@ -187,7 +188,7 @@ impl Actor for ApubSite {
} }
fn private_key_pem(&self) -> Option<String> { fn private_key_pem(&self) -> Option<String> {
self.private_key.clone() self.private_key.clone().map(SensitiveString::into_inner)
} }
fn inbox(&self) -> Url { fn inbox(&self) -> Url {

View File

@ -30,6 +30,7 @@ use lemmy_api_common::{
}, },
}; };
use lemmy_db_schema::{ use lemmy_db_schema::{
sensitive::SensitiveString,
source::{ source::{
activity::ActorType, activity::ActorType,
local_site::LocalSite, local_site::LocalSite,
@ -200,7 +201,7 @@ impl Actor for ApubPerson {
} }
fn private_key_pem(&self) -> Option<String> { fn private_key_pem(&self) -> Option<String> {
self.private_key.clone() self.private_key.clone().map(SensitiveString::into_inner)
} }
fn inbox(&self) -> Url { fn inbox(&self) -> Url {

View File

@ -50,7 +50,7 @@ impl PasswordResetRequest {
) -> Result<PasswordResetRequest, Error> { ) -> Result<PasswordResetRequest, Error> {
let form = PasswordResetRequestForm { let form = PasswordResetRequestForm {
local_user_id: from_local_user_id, local_user_id: from_local_user_id,
token: token_, token: token_.into(),
}; };
Self::create(pool, &form).await Self::create(pool, &form).await
@ -134,7 +134,7 @@ mod tests {
let expected_password_reset_request = PasswordResetRequest { let expected_password_reset_request = PasswordResetRequest {
id: inserted_password_reset_request.id, id: inserted_password_reset_request.id,
local_user_id: inserted_local_user.id, local_user_id: inserted_local_user.id,
token: token.to_string(), token: token.to_string().into(),
published: inserted_password_reset_request.published, published: inserted_password_reset_request.published,
}; };

View File

@ -24,6 +24,7 @@ pub mod aggregates;
#[cfg(feature = "full")] #[cfg(feature = "full")]
pub mod impls; pub mod impls;
pub mod newtypes; pub mod newtypes;
pub mod sensitive;
#[cfg(feature = "full")] #[cfg(feature = "full")]
#[rustfmt::skip] #[rustfmt::skip]
#[allow(clippy::wildcard_imports)] #[allow(clippy::wildcard_imports)]

View File

@ -0,0 +1,57 @@
use serde::{Deserialize, Serialize};
use std::{fmt::Debug, ops::Deref};
#[cfg(feature = "full")]
use ts_rs::TS;
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize, Default)]
#[cfg_attr(feature = "full", derive(DieselNewType))]
#[serde(transparent)]
pub struct SensitiveString(String);
impl SensitiveString {
pub fn into_inner(self) -> String {
self.0
}
}
impl Debug for SensitiveString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Sensitive").finish()
}
}
impl AsRef<[u8]> for SensitiveString {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl Deref for SensitiveString {
type Target = str;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl From<String> for SensitiveString {
fn from(t: String) -> Self {
SensitiveString(t)
}
}
#[cfg(feature = "full")]
impl TS for SensitiveString {
fn name() -> String {
"string".to_string()
}
fn name_with_type_args(_args: Vec<String>) -> String {
"string".to_string()
}
fn dependencies() -> Vec<ts_rs::Dependency> {
Vec::new()
}
fn transparent() -> bool {
true
}
}

View File

@ -2,6 +2,7 @@
use crate::schema::{community, community_follower, community_moderator, community_person_ban}; use crate::schema::{community, community_follower, community_moderator, community_person_ban};
use crate::{ use crate::{
newtypes::{CommunityId, DbUrl, InstanceId, PersonId}, newtypes::{CommunityId, DbUrl, InstanceId, PersonId},
sensitive::SensitiveString,
source::placeholder_apub_url, source::placeholder_apub_url,
CommunityVisibility, CommunityVisibility,
}; };
@ -39,7 +40,7 @@ pub struct Community {
/// Whether the community is local. /// Whether the community is local.
pub local: bool, pub local: bool,
#[serde(skip)] #[serde(skip)]
pub private_key: Option<String>, pub private_key: Option<SensitiveString>,
#[serde(skip)] #[serde(skip)]
pub public_key: String, pub public_key: String,
#[serde(skip)] #[serde(skip)]

View File

@ -2,6 +2,7 @@
use crate::schema::local_user; use crate::schema::local_user;
use crate::{ use crate::{
newtypes::{LocalUserId, PersonId}, newtypes::{LocalUserId, PersonId},
sensitive::SensitiveString,
ListingType, ListingType,
PostListingMode, PostListingMode,
SortType, SortType,
@ -24,8 +25,8 @@ pub struct LocalUser {
/// The person_id for the local user. /// The person_id for the local user.
pub person_id: PersonId, pub person_id: PersonId,
#[serde(skip)] #[serde(skip)]
pub password_encrypted: String, pub password_encrypted: SensitiveString,
pub email: Option<String>, pub email: Option<SensitiveString>,
/// Whether to show NSFW content. /// Whether to show NSFW content.
pub show_nsfw: bool, pub show_nsfw: bool,
pub theme: String, pub theme: String,
@ -47,7 +48,7 @@ pub struct LocalUser {
/// Whether their registration application has been accepted. /// Whether their registration application has been accepted.
pub accepted_application: bool, pub accepted_application: bool,
#[serde(skip)] #[serde(skip)]
pub totp_2fa_secret: Option<String>, pub totp_2fa_secret: Option<SensitiveString>,
/// Open links in a new tab. /// Open links in a new tab.
pub open_links_in_new_tab: bool, pub open_links_in_new_tab: bool,
pub blur_nsfw: bool, pub blur_nsfw: bool,

View File

@ -1,6 +1,6 @@
use crate::newtypes::LocalUserId;
#[cfg(feature = "full")] #[cfg(feature = "full")]
use crate::schema::login_token; use crate::schema::login_token;
use crate::{newtypes::LocalUserId, sensitive::SensitiveString};
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none; use serde_with::skip_serializing_none;
@ -18,7 +18,7 @@ use ts_rs::TS;
pub struct LoginToken { pub struct LoginToken {
/// Jwt token for this login /// Jwt token for this login
#[serde(skip)] #[serde(skip)]
pub token: String, pub token: SensitiveString,
pub user_id: LocalUserId, pub user_id: LocalUserId,
/// Time of login /// Time of login
pub published: DateTime<Utc>, pub published: DateTime<Utc>,
@ -31,7 +31,7 @@ pub struct LoginToken {
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))] #[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
#[cfg_attr(feature = "full", diesel(table_name = login_token))] #[cfg_attr(feature = "full", diesel(table_name = login_token))]
pub struct LoginTokenCreateForm { pub struct LoginTokenCreateForm {
pub token: String, pub token: SensitiveString,
pub user_id: LocalUserId, pub user_id: LocalUserId,
pub ip: Option<String>, pub ip: Option<String>,
pub user_agent: Option<String>, pub user_agent: Option<String>,

View File

@ -1,6 +1,6 @@
use crate::newtypes::LocalUserId;
#[cfg(feature = "full")] #[cfg(feature = "full")]
use crate::schema::password_reset_request; use crate::schema::password_reset_request;
use crate::{newtypes::LocalUserId, sensitive::SensitiveString};
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
#[derive(PartialEq, Eq, Debug)] #[derive(PartialEq, Eq, Debug)]
@ -9,7 +9,7 @@ use chrono::{DateTime, Utc};
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))] #[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))]
pub struct PasswordResetRequest { pub struct PasswordResetRequest {
pub id: i32, pub id: i32,
pub token: String, pub token: SensitiveString,
pub published: DateTime<Utc>, pub published: DateTime<Utc>,
pub local_user_id: LocalUserId, pub local_user_id: LocalUserId,
} }
@ -18,5 +18,5 @@ pub struct PasswordResetRequest {
#[cfg_attr(feature = "full", diesel(table_name = password_reset_request))] #[cfg_attr(feature = "full", diesel(table_name = password_reset_request))]
pub struct PasswordResetRequestForm { pub struct PasswordResetRequestForm {
pub local_user_id: LocalUserId, pub local_user_id: LocalUserId,
pub token: String, pub token: SensitiveString,
} }

View File

@ -2,6 +2,7 @@
use crate::schema::{person, person_follower}; use crate::schema::{person, person_follower};
use crate::{ use crate::{
newtypes::{DbUrl, InstanceId, PersonId}, newtypes::{DbUrl, InstanceId, PersonId},
sensitive::SensitiveString,
source::placeholder_apub_url, source::placeholder_apub_url,
}; };
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
@ -36,7 +37,7 @@ pub struct Person {
/// Whether the person is local to our site. /// Whether the person is local to our site.
pub local: bool, pub local: bool,
#[serde(skip)] #[serde(skip)]
pub private_key: Option<String>, pub private_key: Option<SensitiveString>,
#[serde(skip)] #[serde(skip)]
pub public_key: String, pub public_key: String,
#[serde(skip)] #[serde(skip)]

View File

@ -1,5 +1,6 @@
#[cfg(feature = "full")] #[cfg(feature = "full")]
use crate::schema::secret; use crate::schema::secret;
use crate::sensitive::SensitiveString;
#[derive(Clone)] #[derive(Clone)]
#[cfg_attr(feature = "full", derive(Queryable, Selectable, Identifiable))] #[cfg_attr(feature = "full", derive(Queryable, Selectable, Identifiable))]
@ -7,5 +8,5 @@ use crate::schema::secret;
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))] #[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))]
pub struct Secret { pub struct Secret {
pub id: i32, pub id: i32,
pub jwt_secret: String, pub jwt_secret: SensitiveString,
} }

View File

@ -1,6 +1,9 @@
use crate::newtypes::{DbUrl, InstanceId, SiteId};
#[cfg(feature = "full")] #[cfg(feature = "full")]
use crate::schema::site; use crate::schema::site;
use crate::{
newtypes::{DbUrl, InstanceId, SiteId},
sensitive::SensitiveString,
};
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none; use serde_with::skip_serializing_none;
@ -35,7 +38,7 @@ pub struct Site {
/// The site inbox /// The site inbox
pub inbox_url: DbUrl, pub inbox_url: DbUrl,
#[serde(skip)] #[serde(skip)]
pub private_key: Option<String>, pub private_key: Option<SensitiveString>,
// TODO: mark as `serde(skip)` in next major release as its not needed for api // TODO: mark as `serde(skip)` in next major release as its not needed for api
pub public_key: String, pub public_key: String,
pub instance_id: InstanceId, pub instance_id: InstanceId,