Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • TransFem-org/Sharkey
  • fEmber/Sharkey
  • kopper/Sharkey
  • dakkar/Sharkey-thenautilus
  • esm/Sharkey
  • blueb/Sharkey
  • aura/Sharkey
  • alicem/Sharkey
  • dimkr/Sharkey
  • vvinrg/Sharkey
  • tess/Sharkey
  • Latte_macchiato/Sharkey
  • skyevg/Sharkey
  • TransFem-org/sharkey-trans-fem
  • limepotato/sharkey
  • elrant/villkey
  • kio/kitsukey
  • 4censord/Sharkey
  • kanade/Sharkey
  • kakkokari-gtyih/Sharkey
  • piuvas/Sharkey
  • kio/gaykey
  • owlbear/Sharkey
  • esurio/Sharkey
  • cuteBoiButt/Sharkey
  • magi/Sharkey
  • chikorita157/Sharkey
  • CenTdemeern1/Sharkey
  • GeopJr/Sharkey
  • lhcfl/sharkey
  • cody/Sharkey
  • puppygirlhornypost/Sharkey
  • Sneexy/Sharkey
  • zotan/Sharkey
  • Marie/Sharkey
  • maciejla/Sharkey
  • transitory/Sharkey
  • Caramel/Sharkey
  • fly_mc/Sharkey
  • 87/Sharkey
  • echo/Sharkey
  • transfemsoc/Sharkey
  • ch0ccyra1n/Sharkey
  • interru/Sharkey
  • legiayayana/Sharkey
  • elizabeth-dev/Sharkey
  • JeDaYoshi/Sharkey
47 results
Show changes
Commits on Source (303)
Showing
with 254 additions and 53 deletions
......@@ -229,3 +229,8 @@ checkActivityPubGetSignature: false
# Upload or download file size limits (bytes)
#maxFileSize: 262144000
# CHMod-style permission bits to apply to uploaded files.
# Permission bits are specified as a base-8 string representing User/Group/Other permissions.
# This setting is only useful for custom deployments, such as using a reverse proxy to serve media.
#filePermissionBits: '644'
......@@ -222,3 +222,8 @@ allowedPrivateNetworks: [
# Upload or download file size limits (bytes)
#maxFileSize: 262144000
# CHMod-style permission bits to apply to uploaded files.
# Permission bits are specified as a base-8 string representing User/Group/Other permissions.
# This setting is only useful for custom deployments, such as using a reverse proxy to serve media.
#filePermissionBits: '644'
......@@ -312,3 +312,8 @@ checkActivityPubGetSignature: false
# Upload or download file size limits (bytes)
#maxFileSize: 262144000
# CHMod-style permission bits to apply to uploaded files.
# Permission bits are specified as a base-8 string representing User/Group/Other permissions.
# This setting is only useful for custom deployments, such as using a reverse proxy to serve media.
#filePermissionBits: '644'
......@@ -334,3 +334,8 @@ checkActivityPubGetSignature: false
# PID File of master process
#pidFile: /tmp/misskey.pid
# CHMod-style permission bits to apply to uploaded files.
# Permission bits are specified as a base-8 string representing User/Group/Other permissions.
# This setting is only useful for custom deployments, such as using a reverse proxy to serve media.
#filePermissionBits: '644'
......@@ -3,27 +3,33 @@
🔒 Found a security vulnerability? [Please disclose it responsibly.](https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/SECURITY.md)
🤝 By submitting this feature request, you agree to follow our [Contribution Guidelines.](https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/CONTRIBUTING.md) -->
**What happened?** _(Please give us a brief description of what happened.)_
# **What happened?**
<!-- Please give us a brief description of what happened. -->
**What did you expect to happen?** _(Please give us a brief description of what you expected to happen.)_
# **What did you expect to happen?**
<!-- Please give us a brief description of what you expected to happen. -->
**Version** _(What version of Sharkey is your instance running? You can find this by clicking your instance's logo at the top left and then clicking instance information.)_
# **Version**
<!-- What version of Sharkey is your instance running? You can find this by clicking your instance's logo at the top left and then clicking instance information. -->
**Instance** _(What instance of Sharkey are you using?)_
# **Instance**
<!-- What instance of Sharkey are you using? -->
**What type of issue is this?** _(If this happens on your device and has to do with the user interface, it's client-side. If this happens on either with the API or the backend, or you got a server-side error in the client, it's server-side.)_
# **What type of issue is this?**
<!-- If this happens on your device and has to do with the user interface, it's client-side. If this happens on either with the API or the backend, or you got a server-side error in the client, it's server-side. -->
**What browser are you using? (Client-side issues only)**
# **What browser are you using? (Client-side issues only)**
**What operating system are you using? (Client-side issues only)**
# **What operating system are you using? (Client-side issues only)**
**How do you deploy Sharkey on your server? (Server-side issues only)**
# **How do you deploy Sharkey on your server? (Server-side issues only)**
**What operating system are you using? (Server-side issues only)**
# **What operating system are you using? (Server-side issues only)**
**Relevant log output** _(Please copy and paste any relevant log output. You can find your log by inspecting the page, and going to the "console" tab. This will be automatically formatted into code, so no need for backticks.)_
# **Relevant log output**
<!-- Please copy and paste any relevant log output. You can find your log by inspecting the page, and going to the "console" tab. This will be automatically formatted into code, so no need for backticks. -->
**Contribution Guidelines**
# **Contribution Guidelines**
By submitting this issue, you agree to follow our [Contribution Guidelines](https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/CONTRIBUTING.md)
- [ ] I agree to follow this project's Contribution Guidelines
- [ ] I have searched the issue tracker for similar issues, and this is not a duplicate.
......@@ -3,15 +3,19 @@
🔒 Found a security vulnerability? [Please disclose it responsibly.](https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/SECURITY.md)
🤝 By submitting this feature request, you agree to follow our [Contribution Guidelines.](https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/CONTRIBUTING.md) -->
**What feature would you like implemented?** _(Please give us a brief description of what you'd like.)_
# **What feature would you like implemented?**
<!-- Please give us a brief description of what you'd like. -->
**Why should we add this feature?** _(Please give us a brief description of why your feature is important.)_
# **Why should we add this feature?**
<!-- Please give us a brief description of why your feature is important. -->
**Version** _(What version of Sharkey is your instance running? You can find this by clicking your instance's logo at the top left and then clicking instance information.)_
# **Version**
<!-- What version of Sharkey is your instance running? You can find this by clicking your instance's logo at the top left and then clicking instance information. -->
**Instance** _(What instance of Sharkey are you using?)_
# **Instance**
<!-- What instance of Sharkey are you using? -->
**Contribution Guidelines**
# **Contribution Guidelines**
By submitting this issue, you agree to follow our [Contribution Guidelines](https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/CONTRIBUTING.md)
- [ ] I agree to follow this project's Contribution Guidelines
- [ ] I have searched the issue tracker for similar requests, and this is not a duplicate.
<!-- Thanks for taking the time to make Sharkey better! -->
**What does this PR do?** _(Please give us a brief description of what this PR does.)_
# **What does this MR do?**
<!-- Please give us a brief description of what this PR does. -->
**Contribution Guidelines**
# **Contribution Guidelines**
By submitting this merge request, you agree to follow our [Contribution Guidelines](https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/CONTRIBUTING.md)
- [ ] I agree to follow this project's Contribution Guidelines
- [ ] I have made sure to test this pull request
- [ ] I have made sure to test this merge request
<!-- Uncomment if your merge request has multiple authors -->
<!-- Co-authored-by: Name <email@email.com> -->
# Upgrade Notes
## 2024.10.0
### Hellspawns
Sharkey versions before 2024.10 suffered from a bug in the "Mark instance as NSFW" feature.
When a user from such an instance boosted a note, the boost would be converted to a hellspawn (pure renote with Content Warning).
Hellspawns are buggy and do not properly federate, so it may be desirable to correct any that already exist in the database.
The following script will correct any local or remote hellspawns in the database.
```postgresql
/* Remove "instance is marked as NSFW" hellspawns */
UPDATE "note"
SET "cw" = null
WHERE
"renoteId" IS NOT NULL
AND "text" IS NULL
AND "cw" = 'Instance is marked as NSFW'
AND "replyId" IS NULL
AND "hasPoll" = false
AND "fileIds" = '{}';
/* Fix legacy / user-created hellspawns */
UPDATE "note"
SET "text" = '.'
WHERE
"renoteId" IS NOT NULL
AND "text" IS NULL
AND "cw" IS NOT NULL
AND "replyId" IS NULL
AND "hasPoll" = false
AND "fileIds" = '{}';
```
## 2024.9.0
### Following Feed
......
......@@ -6947,6 +6947,10 @@ export interface Locale extends ILocale {
* Can import notes
*/
"canImportNotes": string;
/**
* Maximum number of scheduled notes
*/
"scheduleNoteMax": string;
};
"_condition": {
/**
......@@ -7396,6 +7400,14 @@ export interface Locale extends ILocale {
* Testers
*/
"testers": string;
/**
* Misskey Contributors
*/
"misskeyContributors": string;
/**
* Our lovely Sponsors
*/
"ourLovelySponsors": string;
};
"_displayOfSensitiveMedia": {
/**
......@@ -8408,6 +8420,14 @@ export interface Locale extends ILocale {
* 違反を報告する
*/
"write:report-abuse": string;
/**
* View your list of scheduled notes
*/
"read:notes-schedule": string;
/**
* Compose or delete scheduled notes
*/
"write:notes-schedule": string;
};
"_auth": {
/**
......@@ -9538,6 +9558,14 @@ export interface Locale extends ILocale {
* Note got edited
*/
"edited": string;
/**
* Posting scheduled note failed
*/
"scheduledNoteFailed": string;
/**
* Scheduled Note was posted
*/
"scheduledNotePosted": string;
};
"_deck": {
/**
......@@ -9661,6 +9689,10 @@ export interface Locale extends ILocale {
* ロールタイムライン
*/
"roleTimeline": string;
/**
* Following
*/
"following": string;
};
};
"_dialog": {
......@@ -10815,6 +10847,14 @@ export interface Locale extends ILocale {
* Stop note search from indexing your public notes.
*/
"makeIndexableDescription": string;
/**
* Enable RSS feed
*/
"enableRss": string;
/**
* Generate an RSS feed containing your basic profile details and public notes. Users can subscribe to the feed without a follow request or approval.
*/
"enableRssDescription": string;
/**
* Require approval for new users
*/
......@@ -11000,6 +11040,44 @@ export interface Locale extends ILocale {
* Show warning when opening external URLs
*/
"warnExternalUrl": string;
/**
* Flash
*/
"flash": string;
"_flash": {
/**
* Flash Content Hidden
*/
"contentHidden": string;
/**
* Powered by Ruffle.
*/
"poweredByRuffle": string;
/**
* Always be wary of arbitrary code execution!
*/
"arbitraryCodeExecutionWarning": string;
/**
* Flash Content Failed To Load:
*/
"failedToLoad": string;
/**
* Flash Content Is Loading
*/
"isLoading": string;
/**
* Loading Ruffle player
*/
"loadingRufflePlayer": string;
/**
* Loading Flash file
*/
"loadingFlashFile": string;
/**
* raw.esm.sh could not be accessed, meaning this instance's Content Security Policy is likely out of date. Please contact your instance administrators.
*/
"cspError": string;
};
"_mfm": {
/**
* This is not a widespread feature, it may not display properly on most other fedi software, including other Misskey forks
......@@ -11374,6 +11452,18 @@ export interface Locale extends ILocale {
* Remote followers may have incomplete or outdated activity
*/
"remoteFollowersWarning": string;
/**
* Select a follow relationship...
*/
"selectFollowRelationship": string;
/**
* Schedule a note
*/
"schedulePost": string;
/**
* List of scheduled notes
*/
"schedulePostList": string;
}
declare const locales: {
[lang: string]: Locale;
......
......@@ -66,13 +66,15 @@
"esbuild": "0.23.1",
"glob": "11.0.0"
},
"optionalDependencies": {
"cypress": "13.14.2"
},
"devDependencies": {
"@misskey-dev/eslint-plugin": "2.0.3",
"@types/node": "20.14.12",
"@typescript-eslint/eslint-plugin": "7.17.0",
"@typescript-eslint/parser": "7.17.0",
"cross-env": "7.0.3",
"cypress": "13.14.2",
"eslint": "9.8.0",
"globals": "15.9.0",
"ncp": "2.0.0",
......
......@@ -42,6 +42,13 @@ export default [
name: '__filename',
message: 'Not in ESModule. Use `import.meta.url` instead.',
}],
// https://typescript-eslint.io/rules/prefer-nullish-coalescing/
'@typescript-eslint/prefer-nullish-coalescing': ['warn', {
ignorePrimitives: {
// Without this, the rule breaks for nullable booleans
boolean: true,
},
}],
},
},
{
......
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class ScheduleNote1699437894737 {
name = 'ScheduleNote1699437894737'
async up(queryRunner) {
await queryRunner.query(`CREATE TABLE "note_schedule" ("id" character varying(32) NOT NULL, "note" jsonb NOT NULL, "userId" character varying(260) NOT NULL, "scheduledAt" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_3a1ae2db41988f4994268218436" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_e798958c40009bf0cdef4f28b5" ON "note_schedule" ("userId") `);
}
async down(queryRunner) {
await queryRunner.query(`DROP TABLE "note_schedule"`);
}
}
export class AddUserEnableRss1733748798177 {
name = 'AddUserEnableRss1733748798177'
async up(queryRunner) {
// Disable by default, then specifically enable for all existing local users.
await queryRunner.query(`ALTER TABLE "user" ADD "enable_rss" boolean NOT NULL DEFAULT false`);
await queryRunner.query(`UPDATE "user" SET "enable_rss" = true WHERE host IS NULL;`)
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "enable_rss"`);
}
}
export class AlterUserHideOnlineStatusDefaultTrue1733754069260 {
name = 'AlterUserHideOnlineStatusDefaultTrue1733754069260'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "hideOnlineStatus" SET DEFAULT true`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "hideOnlineStatus" SET DEFAULT false`);
}
}
......@@ -93,6 +93,7 @@
"@swc/core": "1.6.6",
"@transfem-org/sfm-js": "0.24.5",
"@twemoji/parser": "15.1.1",
"@types/psl": "^1.1.3",
"accepts": "1.3.8",
"ajv": "8.17.1",
"archiver": "7.0.1",
......@@ -135,9 +136,9 @@
"json5": "2.2.3",
"jsonld": "8.3.2",
"jsrsasign": "11.1.0",
"juice": "11.0.0",
"megalodon": "workspace:*",
"meilisearch": "0.42.0",
"juice": "11.0.0",
"microformats-parser": "2.0.2",
"mime-types": "2.1.35",
"misskey-js": "workspace:*",
......@@ -158,6 +159,7 @@
"probe-image-size": "7.2.3",
"promise-limit": "2.7.0",
"proxy-addr": "^2.0.7",
"psl": "^1.13.0",
"pug": "3.0.3",
"punycode": "2.3.1",
"qrcode": "1.5.4",
......
......@@ -12,21 +12,25 @@ import { QueueStatsService } from '@/daemons/QueueStatsService.js';
import { ServerStatsService } from '@/daemons/ServerStatsService.js';
import { ServerService } from '@/server/ServerService.js';
import { MainModule } from '@/MainModule.js';
import { envOption } from '@/env.js';
export async function server() {
const app = await NestFactory.createApplicationContext(MainModule, {
logger: new NestLogger(),
});
const serverService = app.get(ServerService);
await serverService.launch();
if (process.env.NODE_ENV !== 'test') {
app.get(ChartManagementService).start();
app.get(QueueStatsService).start();
app.get(ServerStatsService).start();
await app.get(ChartManagementService).start();
}
if (!envOption.noDaemons) {
await app.get(QueueStatsService).start();
await app.get(ServerStatsService).start();
}
// Start server last so the other services can register hooks first
const serverService = app.get(ServerService);
await serverService.launch();
return app;
}
......@@ -35,8 +39,8 @@ export async function jobQueue() {
logger: new NestLogger(),
});
jobQueue.get(QueueProcessorService).start();
jobQueue.get(ChartManagementService).start();
await jobQueue.get(QueueProcessorService).start();
await jobQueue.get(ChartManagementService).start();
return jobQueue;
}
......@@ -115,6 +115,7 @@ type Source = {
};
pidFile: string;
filePermissionBits?: string;
};
export type Config = {
......@@ -212,6 +213,7 @@ export type Config = {
} | undefined;
pidFile: string;
filePermissionBits?: string;
};
const _filename = fileURLToPath(import.meta.url);
......@@ -347,6 +349,7 @@ export function loadConfig(): Config {
deactivateAntennaThreshold: config.deactivateAntennaThreshold ?? (1000 * 60 * 60 * 24 * 7),
import: config.import,
pidFile: config.pidFile,
filePermissionBits: config.filePermissionBits,
};
}
......@@ -452,7 +455,10 @@ function applyEnvOverrides(config: Source) {
}
}
const alwaysStrings = { 'chmodSocket': true } as { [key: string]: boolean };
const alwaysStrings: { [key in string]?: boolean } = {
'chmodSocket': true,
'filePermissionBits': true,
};
function _assign(path: (string | number)[], lastStep: string | number, value: string) {
let thisConfig = config as any;
......@@ -490,7 +496,7 @@ function applyEnvOverrides(config: Source) {
_apply_top(['sentryForBackend', 'enableNodeProfiling']);
_apply_top([['clusterLimit', 'deliverJobConcurrency', 'inboxJobConcurrency', 'relashionshipJobConcurrency', 'deliverJobPerSec', 'inboxJobPerSec', 'relashionshipJobPerSec', 'deliverJobMaxAttempts', 'inboxJobMaxAttempts']]);
_apply_top([['outgoingAddress', 'outgoingAddressFamily', 'proxy', 'proxySmtp', 'mediaProxy', 'proxyRemoteFiles', 'videoThumbnailGenerator']]);
_apply_top([['maxFileSize', 'maxNoteLength', 'maxRemoteNoteLength', 'maxAltTextLength', 'maxRemoteAltTextLength', 'pidFile']]);
_apply_top([['maxFileSize', 'maxNoteLength', 'maxRemoteNoteLength', 'maxAltTextLength', 'maxRemoteAltTextLength', 'pidFile', 'filePermissionBits']]);
_apply_top(['import', ['downloadTimeout', 'maxFileSize']]);
_apply_top([['signToActivityPubGet', 'checkActivityPubGetSignature']]);
}
......@@ -14,6 +14,8 @@ import { AbuseReportNotificationService } from '@/core/AbuseReportNotificationSe
import { SystemWebhookService } from '@/core/SystemWebhookService.js';
import { UserSearchService } from '@/core/UserSearchService.js';
import { WebhookTestService } from '@/core/WebhookTestService.js';
import { TimeService } from '@/core/TimeService.js';
import { EnvService } from '@/core/EnvService.js';
import { AccountMoveService } from './AccountMoveService.js';
import { AccountUpdateService } from './AccountUpdateService.js';
import { AnnouncementService } from './AnnouncementService.js';
......@@ -381,6 +383,8 @@ const $SponsorsService: Provider = { provide: 'SponsorsService', useExisting: Sp
ChannelFollowingService,
RegistryApiService,
ReversiService,
TimeService,
EnvService,
ChartLoggerService,
FederationChart,
......@@ -680,6 +684,8 @@ const $SponsorsService: Provider = { provide: 'SponsorsService', useExisting: Sp
ChannelFollowingService,
RegistryApiService,
ReversiService,
TimeService,
EnvService,
FederationChart,
NotesChart,
......
......@@ -6,7 +6,6 @@
import * as fs from 'node:fs';
import * as stream from 'node:stream/promises';
import { Inject, Injectable } from '@nestjs/common';
import ipaddr from 'ipaddr.js';
import chalk from 'chalk';
import got, * as Got from 'got';
import { parse } from 'content-disposition';
......@@ -70,13 +69,6 @@ export class DownloadService {
},
enableUnixSockets: false,
}).on('response', (res: Got.Response) => {
if ((process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test') && !this.config.proxy && res.ip) {
if (this.isPrivateIp(res.ip)) {
this.logger.warn(`Blocked address: ${res.ip}`);
req.destroy();
}
}
const contentLength = res.headers['content-length'];
if (contentLength != null) {
const size = Number(contentLength);
......@@ -139,18 +131,4 @@ export class DownloadService {
cleanup();
}
}
@bindThis
private isPrivateIp(ip: string): boolean {
const parsedIp = ipaddr.parse(ip);
for (const net of this.config.allowedPrivateNetworks ?? []) {
const cidr = ipaddr.parseCIDR(net);
if (cidr[0].kind() === parsedIp.kind() && parsedIp.match(ipaddr.parseCIDR(net))) {
return false;
}
}
return parsedIp.range() !== 'unicast';
}
}
......@@ -312,6 +312,7 @@ export class EmailService {
Accept: 'application/json',
Authorization: truemailAuthKey,
},
isLocalAddressAllowed: true,
});
const json = (await res.json()) as {
......