Compare commits

..

No commits in common. "bcff0a4eece9b66cb69b8e7fa8ef5f7ad07fba39" and "23bd522adef96a36307b2f15232902bf444418b7" have entirely different histories.

15 changed files with 87 additions and 124 deletions

View file

@ -52,21 +52,12 @@ jobs:
- uses: DeterminateSystems/nix-installer-action@main - uses: DeterminateSystems/nix-installer-action@main
with: with:
extra-conf: accept-flake-config = true extra-conf: accept-flake-config = true
- uses: DeterminateSystems/flakehub-cache-action@main - uses: DeterminateSystems/magic-nix-cache-action@main
- uses: DeterminateSystems/flake-checker-action@main - uses: DeterminateSystems/flake-checker-action@main
- name: Build docker package - name: Build docker package
run: nix build .#ociImage run: nix build .#ociImage
- name: Load Docker image - name: Load Docker image
run: docker load < result run: docker load < result
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: 'ghcr.io/${{ env.IMAGE_NAME }}:main'
format: 'table'
exit-code: '1'
ignore-unfixed: true
vuln-type: 'os,library'
severity: 'CRITICAL,HIGH'
- name: Push image to registry - name: Push image to registry
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request'
run: docker push ghcr.io/$IMAGE_NAME -a run: docker push ghcr.io/$IMAGE_NAME -a

View file

@ -19,7 +19,7 @@ jobs:
- uses: DeterminateSystems/nix-installer-action@main - uses: DeterminateSystems/nix-installer-action@main
with: with:
extra-conf: accept-flake-config = true extra-conf: accept-flake-config = true
- uses: DeterminateSystems/flakehub-cache-action@main - uses: DeterminateSystems/magic-nix-cache-action@main
- uses: DeterminateSystems/flake-checker-action@main - uses: DeterminateSystems/flake-checker-action@main
- name: Build default package - name: Build default package
run: nix build . run: nix build .

46
flake.lock generated
View file

@ -2,12 +2,12 @@
"nodes": { "nodes": {
"flake-compat": { "flake-compat": {
"locked": { "locked": {
"lastModified": 1733328505, "lastModified": 1696426674,
"narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"revCount": 69, "revCount": 57,
"type": "tarball", "type": "tarball",
"url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.1.0/01948eb7-9cba-704f-bbf3-3fa956735b52/source.tar.gz?rev=ff81ac966bb2cae68946d5ed5fc4994f96d0ffec&revCount=69" "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
}, },
"original": { "original": {
"type": "tarball", "type": "tarball",
@ -19,11 +19,11 @@
"nixpkgs-lib": "nixpkgs-lib" "nixpkgs-lib": "nixpkgs-lib"
}, },
"locked": { "locked": {
"lastModified": 1738453229, "lastModified": 1730504689,
"narHash": "sha256-7H9XgNiGLKN1G1CgRh0vUL4AheZSYzPm+zmZ7vxbJdo=", "narHash": "sha256-hgmguH29K2fvs9szpq2r3pz2/8cJd2LPS+b4tfNFCwE=",
"owner": "hercules-ci", "owner": "hercules-ci",
"repo": "flake-parts", "repo": "flake-parts",
"rev": "32ea77a06711b758da0ad9bd6a844c5740a87abd", "rev": "506278e768c2a08bec68eb62932193e341f55c90",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -37,11 +37,11 @@
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
}, },
"locked": { "locked": {
"lastModified": 1736429655, "lastModified": 1721727458,
"narHash": "sha256-BwMekRuVlSB9C0QgwKMICiJ5EVbLGjfe4qyueyNQyGI=", "narHash": "sha256-r/xppY958gmZ4oTfLiHN0ZGuQ+RSTijDblVgVLFi1mw=",
"owner": "nix-community", "owner": "nix-community",
"repo": "naersk", "repo": "naersk",
"rev": "0621e47bd95542b8e1ce2ee2d65d6a1f887a13ce", "rev": "3fb418eaf352498f6b6c30592e3beb63df42ef11",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -53,8 +53,8 @@
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 0, "lastModified": 0,
"narHash": "sha256-8Eo/jRAgT3CbAloyqOj6uPN1EqBvLI/Tv2g+RxHjkhU=", "narHash": "sha256-xb4/Y+Y7ZlkQaA5rXnrXplDzdt2Jfgdmar3+qkb56UA=",
"path": "/nix/store/vg3rs6imxilxn66gf6vb8m98d7ib35f8-source", "path": "/nix/store/bc6afipyc33jj5iwp10acc848jj3fswr-source",
"type": "path" "type": "path"
}, },
"original": { "original": {
@ -64,23 +64,23 @@
}, },
"nixpkgs-lib": { "nixpkgs-lib": {
"locked": { "locked": {
"lastModified": 1738452942, "lastModified": 1730504152,
"narHash": "sha256-vJzFZGaCpnmo7I6i416HaBLpC+hvcURh/BQwROcGIp8=", "narHash": "sha256-lXvH/vOfb4aGYyvFmZK/HlsNsr/0CVWlwYvo2rxJk3s=",
"type": "tarball", "type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" "url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz"
}, },
"original": { "original": {
"type": "tarball", "type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" "url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz"
} }
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1739020877, "lastModified": 1731676054,
"narHash": "sha256-mIvECo/NNdJJ/bXjNqIh8yeoSjVLAuDuTUzAo7dzs8Y=", "narHash": "sha256-OZiZ3m8SCMfh3B6bfGC/Bm4x3qc1m2SVEAlkV6iY7Yg=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "a79cfe0ebd24952b580b1cf08cd906354996d547", "rev": "5e4fbfb6b3de1aa2872b76d49fafc942626e2add",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -122,11 +122,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1738953846, "lastModified": 1732013921,
"narHash": "sha256-yrK3Hjcr8F7qS/j2F+r7C7o010eVWWlm4T1PrbKBOxQ=", "narHash": "sha256-grEEN4LjL4DTDZUyZjVcj9dXRykH/SKnpOIADN0q5w8=",
"owner": "numtide", "owner": "numtide",
"repo": "treefmt-nix", "repo": "treefmt-nix",
"rev": "4f09b473c936d41582dd744e19f34ec27592c5fd", "rev": "5f5c2787576f3e39bbc2ebdbf8521b3177c5c19c",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -1,18 +1,8 @@
use crate::{ use crate::{
database::StateHandle, database::StateHandle, entities::{self, post, prelude, user}, error::Error, objects::{
entities::{self, post, prelude, user},
error::Error,
objects::{
person::DbUser, person::DbUser,
post::{DbPost, Note}, post::{DbPost, Note},
}, }, utils::{base_url_encode, generate_create_id, generate_random_object_id}, versia::{conversion::{versia_post_from_db, versia_user_from_db}, objects::SortAlphabetically, superx::request_client}, API_DOMAIN, AUTH, DB
utils::{base_url_encode, generate_create_id, generate_random_object_id},
versia::{
conversion::{versia_post_from_db, versia_user_from_db},
objects::SortAlphabetically,
superx::request_client,
},
API_DOMAIN, AUTH, DB,
}; };
use activitypub_federation::{ use activitypub_federation::{
activity_sending::SendActivityTask, activity_sending::SendActivityTask,
@ -85,9 +75,13 @@ impl CreatePost {
id: generate_create_id(data.domain(), &db_entry.id, &encoded_url)?, id: generate_create_id(data.domain(), &db_entry.id, &encoded_url)?,
}; };
let create_with_context = WithContext::new_default(create); let create_with_context = WithContext::new_default(create);
let sends = let sends = SendActivityTask::prepare(
SendActivityTask::prepare(&create_with_context, &data.local_user().await?, inbox, data) &create_with_context,
.await?; &data.local_user().await?,
inbox,
data,
)
.await?;
for send in sends { for send in sends {
send.sign_and_send(data).await?; send.sign_and_send(data).await?;
} }
@ -136,9 +130,9 @@ async fn federate_inbox(note: crate::entities::post::Model) -> anyhow::Result<()
let db = DB.get().unwrap(); let db = DB.get().unwrap();
let list_model = entities::prelude::FollowRelation::find() let list_model = entities::prelude::FollowRelation::find()
.filter(entities::follow_relation::Column::FolloweeId.eq(note.creator.to_string())) .filter(entities::follow_relation::Column::FolloweeId.eq(note.creator.to_string()))
.all(db) .all(db)
.await?; .await?;
let mut list_url = Vec::new(); let mut list_url = Vec::new();
@ -156,11 +150,9 @@ async fn federate_inbox(note: crate::entities::post::Model) -> anyhow::Result<()
let model = prelude::User::find() let model = prelude::User::find()
.filter(user::Column::Id.eq(note.creator.as_str())) .filter(user::Column::Id.eq(note.creator.as_str()))
.one(db) .one(db)
.await? .await?.unwrap();
.unwrap();
for inbox in array { for inbox in array {
let push = req_client let push = req_client.post(inbox.clone())
.post(inbox.clone())
.bearer_auth(AUTH.to_string()) .bearer_auth(AUTH.to_string())
.json(&SortAlphabetically(&versia_post)); .json(&SortAlphabetically(&versia_post));
warn!("{}", inbox.to_string()); warn!("{}", inbox.to_string());
@ -170,7 +162,7 @@ async fn federate_inbox(note: crate::entities::post::Model) -> anyhow::Result<()
Ok(()) Ok(())
} }
async fn push_to_inbox(req: RequestBuilder) -> anyhow::Result<()> { async fn push_to_inbox(req: RequestBuilder) -> anyhow::Result<()>{
let req_client = request_client(); let req_client = request_client();
let response = req_client.execute(req.build()?).await?; let response = req_client.execute(req.build()?).await?;

View file

@ -17,8 +17,8 @@ use crate::{
post, prelude, user, post, prelude, user,
}, },
error, error,
utils::{generate_follow_accept_id, generate_random_object_id},
versia::funcs::send_follow_accept_to_versia, versia::funcs::send_follow_accept_to_versia,
utils::{generate_follow_accept_id, generate_random_object_id},
DB, DB,
}; };

View file

@ -2,12 +2,12 @@ use crate::{
database::StateHandle, database::StateHandle,
entities::user, entities::user,
error::Error, error::Error,
objects::person::{DbUser, PersonAcceptedActivities},
utils::generate_user_id,
versia::{ versia::{
self, self,
conversion::{db_user_from_url, local_db_user_from_name, receive_versia_note}, conversion::{db_user_from_url, local_db_user_from_name, receive_versia_note},
}, },
objects::person::{DbUser, PersonAcceptedActivities},
utils::generate_user_id,
API_DOMAIN, LYSAND_DOMAIN, API_DOMAIN, LYSAND_DOMAIN,
}; };
use activitypub_federation::{ use activitypub_federation::{

View file

@ -15,6 +15,9 @@ use clap::Parser;
use database::Database; use database::Database;
use entities::post; use entities::post;
use http::{http_get_user, http_post_user_inbox, webfinger}; use http::{http_get_user, http_post_user_inbox, webfinger};
use versia::http::{
create_activity, fetch_versia_post, fetch_post, fetch_user, versia_inbox, query_post,
};
use objects::person::{DbUser, Person}; use objects::person::{DbUser, Person};
use sea_orm::{ActiveModelTrait, DatabaseConnection, Set}; use sea_orm::{ActiveModelTrait, DatabaseConnection, Set};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -29,9 +32,6 @@ use tracing::{info, instrument::WithSubscriber};
use url::Url; use url::Url;
use utils::generate_object_id; use utils::generate_object_id;
use uuid::Uuid; use uuid::Uuid;
use versia::http::{
create_activity, fetch_post, fetch_user, fetch_versia_post, query_post, versia_inbox,
};
use crate::{ use crate::{
activities::create_post::CreatePost, activities::create_post::CreatePost,
@ -47,9 +47,9 @@ mod database;
mod entities; mod entities;
mod error; mod error;
mod http; mod http;
mod versia;
mod objects; mod objects;
mod utils; mod utils;
mod versia;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct Response { struct Response {

View file

@ -188,7 +188,10 @@ impl Object for user::Model {
Ok(()) Ok(())
} }
async fn from_json(json: Self::Kind, data: &Data<Self::DataType>) -> Result<Self, Self::Error> { async fn from_json(
json: Self::Kind,
data: &Data<Self::DataType>,
) -> Result<Self, Self::Error> {
let query = User::find() let query = User::find()
.filter(user::Column::Url.eq(json.id.inner().as_str())) .filter(user::Column::Url.eq(json.id.inner().as_str()))
.one(data.database_connection.as_ref()) .one(data.database_connection.as_ref())

View file

@ -1,11 +1,5 @@
use crate::{ use crate::{
activities::create_post::CreatePost, activities::create_post::CreatePost, database::StateHandle, entities::{prelude::Post, user, post}, error::Error, objects::person::DbUser, utils::generate_object_id, versia::conversion::db_user_from_url
database::StateHandle,
entities::{post, prelude::Post, user},
error::Error,
objects::person::DbUser,
utils::generate_object_id,
versia::conversion::db_user_from_url,
}; };
use activitypub_federation::{ use activitypub_federation::{
config::Data, config::Data,

View file

@ -146,12 +146,10 @@ pub async fn versia_user_from_db(
} else { } else {
inbox_url = Url::parse(&("https://".to_string() + &API_DOMAIN + "/apbridge/versia/inbox"))?; inbox_url = Url::parse(&("https://".to_string() + &API_DOMAIN + "/apbridge/versia/inbox"))?;
followers_url = Url::parse( followers_url = Url::parse(
("https://".to_string() + &API_DOMAIN + "/apbridge/versia/followers/" + &user.id) ("https://".to_string() + &API_DOMAIN + "/apbridge/versia/followers/" + &user.id).as_str(),
.as_str(),
)?; )?;
following_url = Url::parse( following_url = Url::parse(
("https://".to_string() + &API_DOMAIN + "/apbridge/versia/following/" + &user.id) ("https://".to_string() + &API_DOMAIN + "/apbridge/versia/following/" + &user.id).as_str(),
.as_str(),
)?; )?;
} }
@ -491,9 +489,9 @@ pub async fn receive_versia_note(
db_id: String, db_id: String,
) -> anyhow::Result<entities::post::Model> { ) -> anyhow::Result<entities::post::Model> {
let post_res: Option<post::Model> = prelude::Post::find() let post_res: Option<post::Model> = prelude::Post::find()
.filter(entities::post::Column::Id.eq(note.id.to_string())) .filter(entities::post::Column::Id.eq(note.id.to_string()))
.one(DB.get().unwrap()) .one(DB.get().unwrap())
.await?; .await?;
if let Some(post) = post_res { if let Some(post) = post_res {
return Ok(post); return Ok(post);
@ -524,18 +522,10 @@ pub async fn receive_versia_note(
kind: Default::default(), kind: Default::default(),
}); });
continue; continue;
} else if !(l_tag.clone().to_string().contains(LYSAND_DOMAIN.as_str()) } else if !(l_tag.clone().to_string().contains(LYSAND_DOMAIN.as_str()) || l_tag.clone().to_string().contains(domain)) {
|| l_tag.clone().to_string().contains(domain)) println!("{}", l_tag.clone().to_string().contains(LYSAND_DOMAIN.as_str()) );
{
println!(
"{}",
l_tag.clone().to_string().contains(LYSAND_DOMAIN.as_str())
);
println!("{}", l_tag.clone().to_string().contains(domain)); println!("{}", l_tag.clone().to_string().contains(domain));
println!( println!("-------------- {} -----------------a", l_tag.clone().to_string());
"-------------- {} -----------------a",
l_tag.clone().to_string()
);
tag.push(Mention { tag.push(Mention {
href: l_tag, href: l_tag,
kind: Default::default(), kind: Default::default(),
@ -544,8 +534,10 @@ pub async fn receive_versia_note(
} }
println!("+++++++ --------- ++++++++++"); println!("+++++++ --------- ++++++++++");
let user = db_user_from_url(l_tag).await?; let user = db_user_from_url(l_tag).await?;
let ap_url = let ap_url = Url::parse(&format!(
Url::parse(&format!("https://{}/apbridge/user/{}", domain, user.id).to_string())?; "https://{}/apbridge/user/{}",
domain, user.id
).to_string())?;
tag.push(Mention { tag.push(Mention {
href: ap_url, href: ap_url,
kind: Default::default(), kind: Default::default(),
@ -626,11 +618,12 @@ pub async fn receive_versia_note(
to, to,
tag, tag,
attributed_to: { attributed_to: {
let user = db_user_from_url(Url::parse(user.uri.clone().as_str()).unwrap()).await?; let user = db_user_from_url(Url::parse(user.uri.clone().as_str()).unwrap()).await?;
let ap_url = Url::parse( let ap_url = Url::parse(&format!(
&format!("https://{}/apbridge/user/{}", domain, user.id).to_string(), "https://{}/apbridge/user/{}",
)?; domain, user.id
ap_url.into() ).to_string())?;
ap_url.into()
}, },
content: option_content_format_text(note.content) content: option_content_format_text(note.content)
.await .await

View file

@ -16,12 +16,12 @@ use crate::{
prelude, user, prelude, user,
}, },
error, error,
objects::{self, person::Person},
utils::{base_url_decode, generate_create_id, generate_user_id},
versia::{ versia::{
conversion::{versia_post_from_db, versia_user_from_db}, conversion::{versia_post_from_db, versia_user_from_db},
inbox::inbox_entry, inbox::inbox_entry,
}, },
objects::{self, person::Person},
utils::{base_url_decode, generate_create_id, generate_user_id},
Response, API_DOMAIN, DB, FEDERATION_CONFIG, Response, API_DOMAIN, DB, FEDERATION_CONFIG,
}; };

View file

@ -1,13 +1,9 @@
use crate::{ use crate::{
activities::{create_post::CreatePost, follow::Follow}, activities::{create_post::CreatePost, follow::Follow}, entities::{
entities::{
self, follow_relation, self, follow_relation,
prelude::{self, FollowRelation}, prelude::{self, FollowRelation},
user, user,
}, }, utils::generate_follow_req_id, versia::http::main_versia_url_to_user_and_model, API_DOMAIN, DB, FEDERATION_CONFIG
utils::generate_follow_req_id,
versia::http::main_versia_url_to_user_and_model,
API_DOMAIN, DB, FEDERATION_CONFIG,
}; };
use activitypub_federation::{ use activitypub_federation::{
activity_sending::SendActivityTask, fetch::object_id::ObjectId, protocol::context::WithContext, activity_sending::SendActivityTask, fetch::object_id::ObjectId, protocol::context::WithContext,
@ -157,10 +153,7 @@ async fn get_inbox_vec(ap_note: &crate::objects::post::Note) -> Vec<Url> {
let mut inbox: Vec<Url> = Vec::new(); let mut inbox: Vec<Url> = Vec::new();
let entry = ap_note.to.get(0).unwrap(); let entry = ap_note.to.get(0).unwrap();
if entry if entry.to_string().eq_ignore_ascii_case(public().to_string().as_str()) {
.to_string()
.eq_ignore_ascii_case(public().to_string().as_str())
{
let (_, mentions) = ap_note.to.split_at(2); let (_, mentions) = ap_note.to.split_at(2);
inbox_users.append(&mut mentions.to_vec()); inbox_users.append(&mut mentions.to_vec());
} else { } else {
@ -170,14 +163,13 @@ async fn get_inbox_vec(ap_note: &crate::objects::post::Note) -> Vec<Url> {
inbox_users.dedup(); inbox_users.dedup();
let conf = FEDERATION_CONFIG.get().unwrap(); let conf = FEDERATION_CONFIG.get().unwrap();
let data = &conf.to_request_data(); let data = &conf.to_request_data();
for user in inbox_users { for user in inbox_users {
let ap_user = ObjectId::<user::Model>::from(user) let ap_user = ObjectId::<user::Model>::from(user).dereference(data)
.dereference(data) .await.unwrap();
.await
.unwrap();
inbox.push(Url::parse(&ap_user.inbox).unwrap()); inbox.push(Url::parse(&ap_user.inbox).unwrap());
} }

View file

@ -266,12 +266,12 @@ pub struct UserCollections {
pub following: Url, pub following: Url,
#[serde( #[serde(
skip_serializing_if = "Option::is_none", skip_serializing_if = "Option::is_none",
rename = "pub.versia:likes/Likes" rename="pub.versia:likes/Likes"
)] )]
pub likes: Option<Url>, pub likes: Option<Url>,
#[serde( #[serde(
skip_serializing_if = "Option::is_none", skip_serializing_if = "Option::is_none",
rename = "pub.versia:likes/Dislikes" rename="pub.versia:likes/Dislikes"
)] )]
pub dislikes: Option<Url>, pub dislikes: Option<Url>,
} }

View file

@ -15,7 +15,9 @@ pub async fn deserialize_versia_type(data: String) -> anyhow::Result<String> {
Ok(versia_type) Ok(versia_type)
} }
pub async fn serialize_versia_type(versia_type: String) -> anyhow::Result<String> { pub async fn serialize_versia_type(
versia_type: String,
) -> anyhow::Result<String> {
let data = serde_json::to_string(&versia_type)?; let data = serde_json::to_string(&versia_type)?;
Ok(data) Ok(data)
} }

View file

@ -13,11 +13,7 @@ async fn test_user_serial() {
let user = super::superx::deserialize_user(response.text().await.unwrap()) let user = super::superx::deserialize_user(response.text().await.unwrap())
.await .await
.unwrap(); .unwrap();
let response_outbox = client let response_outbox = client.get(user.collections.outbox.as_str()).send().await.unwrap();
.get(user.collections.outbox.as_str())
.send()
.await
.unwrap();
let outbox = super::superx::deserialize_outbox(response_outbox.text().await.unwrap()) let outbox = super::superx::deserialize_outbox(response_outbox.text().await.unwrap())
.await .await
.unwrap(); .unwrap();