mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
Add more contribution help
This commit is contained in:
parent
460b68c381
commit
35f54d108f
133
CODE_OF_CONDUCT.md
Normal file
133
CODE_OF_CONDUCT.md
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||
identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the overall
|
||||
community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or advances of
|
||||
any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email address,
|
||||
without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
[INSERT CONTACT METHOD].
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series of
|
||||
actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or permanent
|
||||
ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||
community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.1, available at
|
||||
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
||||
|
||||
Community Impact Guidelines were inspired by
|
||||
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
|
||||
[https://www.contributor-covenant.org/translations][translations].
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
||||
[Mozilla CoC]: https://github.com/mozilla/diversity
|
||||
[FAQ]: https://www.contributor-covenant.org/faq
|
||||
[translations]: https://www.contributor-covenant.org/translations
|
||||
64
CONTRIBUTING.md
Normal file
64
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# Contributing to Lysand
|
||||
Thank you for your interest in contributing to Lysand! We welcome contributions from everyone, regardless of their level of experience or expertise.
|
||||
|
||||
## Getting Started
|
||||
To get started, please follow these steps:
|
||||
|
||||
1. Fork the repository, clone it on your local system and make your own branch
|
||||
2. Install the [Bun](https://bun.sh) runtime:
|
||||
```sh
|
||||
curl -fsSL https://bun.sh/install | bash
|
||||
```
|
||||
3. Run `bun install` in the project directory to install the dependencies
|
||||
```sh
|
||||
bun install
|
||||
```
|
||||
> You will need a running PostgreSQL database for the next step
|
||||
|
||||
> If you don't have a running PostgreSQL instance, you can use the following `docker-compose.yml` file to start one:
|
||||
> ```yaml
|
||||
>services:
|
||||
> db:
|
||||
> image: postgres:13-alpine
|
||||
> restart: always
|
||||
> init: true
|
||||
> environment: {
|
||||
> POSTGRES_USER: fediproject,
|
||||
> POSTGRES_PASSWORD: fediproject,
|
||||
> POSTGRES_DB: fediproject
|
||||
> }
|
||||
> ports:
|
||||
> - 5432:5432
|
||||
> volumes:
|
||||
> - ./data:/var/lib/postgresql/data
|
||||
> ```
|
||||
|
||||
4. Copy the `config/config.example.toml` file to `config/config.toml` and change the database connection values to your own Postgres instance
|
||||
> For the example above, the values would be:
|
||||
> ```toml
|
||||
> [database]
|
||||
> host = "localhost"
|
||||
> port = 5432
|
||||
> username = "fediproject"
|
||||
> password = "fediproject"
|
||||
> database = "fediproject"
|
||||
> ```
|
||||
5. Fill in the rest of the config file with your own configuration (you can leave most things to the default)
|
||||
|
||||
## Testing your changes
|
||||
|
||||
To start the live server on the address and port specified on the config file, run:
|
||||
```sh
|
||||
bun dev
|
||||
```
|
||||
|
||||
If your port number is lower than 1024, you may need to run the command as root.
|
||||
|
||||
## Running tests
|
||||
|
||||
To run the tests, run:
|
||||
```sh
|
||||
bun test
|
||||
```
|
||||
|
||||
The tests are located in the `tests/` directory and follow a Jest-like syntax.
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
# Lysand
|
||||
|
||||
      
|
||||
       [](code_of_conduct.md)
|
||||
|
||||
|
||||
## What is this?
|
||||
|
||||
|
|
|
|||
64
classes/activitypub.ts
Normal file
64
classes/activitypub.ts
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import { APActivity, APActor } from "activitypub-types";
|
||||
|
||||
export class RemoteActor {
|
||||
private actorData: APActor | null;
|
||||
private actorUri: string;
|
||||
|
||||
constructor(actor: APActor | string) {
|
||||
if (typeof actor === "string") {
|
||||
this.actorUri = actor;
|
||||
this.actorData = null;
|
||||
} else {
|
||||
this.actorUri = actor.id || "";
|
||||
this.actorData = actor;
|
||||
}
|
||||
}
|
||||
|
||||
public async fetch() {
|
||||
const response = await fetch(this.actorUri);
|
||||
const actorJson = (await response.json()) as APActor;
|
||||
this.actorData = actorJson;
|
||||
}
|
||||
|
||||
public getData() {
|
||||
return this.actorData;
|
||||
}
|
||||
}
|
||||
|
||||
export class RemoteActivity {
|
||||
private data: APActivity | null;
|
||||
private uri: string;
|
||||
|
||||
constructor(uri: string, data: APActivity | null) {
|
||||
this.uri = uri;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public async fetch() {
|
||||
const response = await fetch(this.uri);
|
||||
const json = (await response.json()) as APActivity;
|
||||
this.data = json;
|
||||
}
|
||||
|
||||
public getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public async getActor() {
|
||||
if (!this.data) {
|
||||
throw new Error("No data");
|
||||
}
|
||||
|
||||
if (Array.isArray(this.data.actor)) {
|
||||
throw new Error("Multiple actors");
|
||||
}
|
||||
|
||||
if (typeof this.data.actor === "string") {
|
||||
const actor = new RemoteActor(this.data.actor);
|
||||
await actor.fetch();
|
||||
return actor.getData();
|
||||
}
|
||||
|
||||
return new RemoteActor(this.data.actor as any);
|
||||
}
|
||||
}
|
||||
|
|
@ -223,7 +223,7 @@ export class Status extends BaseEntity {
|
|||
id: `${config.http.base_url}/users/${data.account.username}/statuses/${newStatus.id}`,
|
||||
type: "Note",
|
||||
summary: data.spoiler_text,
|
||||
content: data.content, // TODO: Format as HTML
|
||||
content: data.content,
|
||||
inReplyTo: data.reply?.object
|
||||
? data.reply.object.data.id
|
||||
: undefined,
|
||||
|
|
|
|||
|
|
@ -214,6 +214,8 @@ export class User extends BaseEntity {
|
|||
* Fetches the list of followers associated with the actor and updates the user's followers
|
||||
*/
|
||||
async fetchFollowers() {
|
||||
const config = getConfig();
|
||||
|
||||
let followers: APOrderedCollectionPage = await fetch(
|
||||
`${this.actor.data.followers?.toString() ?? ""}?page=1`,
|
||||
{
|
||||
|
|
@ -234,7 +236,10 @@ export class User extends BaseEntity {
|
|||
};
|
||||
}
|
||||
|
||||
// TODO: integrate followers
|
||||
if (config.activitypub.fetch_all_collection_members) {
|
||||
// Loop through followers list and retrieve each actor individually
|
||||
// TODO: Implement
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
49
server/api/api/v1/statuses/[id]/context.ts
Normal file
49
server/api/api/v1/statuses/[id]/context.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
import { applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { MatchedRoute } from "bun";
|
||||
import { RawObject } from "~database/entities/RawObject";
|
||||
import { Status } from "~database/entities/Status";
|
||||
import { User } from "~database/entities/User";
|
||||
import { APIRouteMeta } from "~types/api";
|
||||
|
||||
export const meta: APIRouteMeta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
ratelimits: {
|
||||
max: 100,
|
||||
duration: 60,
|
||||
},
|
||||
route: "/api/v1/statuses/:id/context",
|
||||
auth: {
|
||||
required: false,
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Fetch a user
|
||||
*/
|
||||
export default async (
|
||||
req: Request,
|
||||
matchedRoute: MatchedRoute
|
||||
): Promise<Response> => {
|
||||
// Public for public statuses limited to 40 ancestors and 60 descendants with a maximum depth of 20.
|
||||
// User token + read:statuses for up to 4,096 ancestors, 4,096 descendants, unlimited depth, and private statuses.
|
||||
const id = matchedRoute.params.id;
|
||||
|
||||
const { user } = await User.getFromRequest(req);
|
||||
|
||||
let foundStatus: RawObject | null;
|
||||
try {
|
||||
foundStatus = await RawObject.findOneBy({
|
||||
id,
|
||||
});
|
||||
} catch (e) {
|
||||
return errorResponse("Invalid ID", 404);
|
||||
}
|
||||
|
||||
if (!foundStatus) return errorResponse("Record not found", 404);
|
||||
|
||||
// Get all ancestors
|
||||
const ancestors = await foundStatus.getAncestors();
|
||||
|
||||
return jsonResponse({});
|
||||
};
|
||||
|
|
@ -71,7 +71,16 @@ export default async (
|
|||
// Delete status and all associated objects
|
||||
await status.object.remove();
|
||||
|
||||
return jsonResponse({}, 200);
|
||||
return jsonResponse(
|
||||
{
|
||||
...(await status.toAPI()),
|
||||
// TODO: Add
|
||||
// text: Add source text
|
||||
// poll: Add source poll
|
||||
// media_attachments
|
||||
},
|
||||
200
|
||||
);
|
||||
}
|
||||
|
||||
return jsonResponse({});
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ export interface ConfigType {
|
|||
discard_follows: string[];
|
||||
force_sensitive: string[];
|
||||
remove_media: string[];
|
||||
fetch_all_colletion_members: boolean;
|
||||
fetch_all_collection_members: boolean;
|
||||
authorized_fetch: boolean;
|
||||
};
|
||||
|
||||
|
|
@ -244,7 +244,7 @@ export const configDefaults: ConfigType = {
|
|||
discard_updates: [],
|
||||
discard_follows: [],
|
||||
remove_media: [],
|
||||
fetch_all_colletion_members: false,
|
||||
fetch_all_collection_members: false,
|
||||
authorized_fetch: false,
|
||||
},
|
||||
filters: {
|
||||
|
|
|
|||
Loading…
Reference in a new issue