diff --git a/.config/example.yml b/.config/example.yml index 4c9f4df07..5cf984e9e 100644 --- a/.config/example.yml +++ b/.config/example.yml @@ -1,5 +1,5 @@ #━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -# Misskey configuration +# Calckey configuration #━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # ┌─────┐ @@ -38,11 +38,11 @@ db: port: 5432 # Database name - db: misskey + db: calckey # Auth - user: example-misskey-user - pass: example-misskey-pass + user: example-calckey-user + pass: example-calckey-pass # Whether disable Caching queries #disableCache: true @@ -147,7 +147,8 @@ id: 'aid' # Managed hosting settings # !!!!!!!!!! -# >>>>>> NORMAL SELF-HOSTERS, STAY AWAY! YOU DON'T NEED THIS! <<<<<< +# >>>>>> NORMAL SELF-HOSTERS, STAY AWAY! <<<<<< +# >>>>>> YOU DON'T NEED THIS! <<<<<< # !!!!!!!!!! # Each category is optional, but if each item in each category is mandatory! # If you mess this up, that's on you, you've been warned... @@ -181,4 +182,11 @@ id: 'aid' # connnectOverProxy: false # setPublicReadOnUpload: true # s3ForcePathStyle: true -#summalyProxyUrl: 'https://summaly.arkjp.net' + +# !!!!!!!!!! +# >>>>>> AGAIN, NORMAL SELF-HOSTERS, STAY AWAY! <<<<<< +# >>>>>> YOU DON'T NEED THIS, ABOVE SETTINGS ARE FOR MANAGED HOSTING ONLY! <<<<<< +# !!!!!!!!!! + +# Seriously. Do NOT fill out the above settings if you're self-hosting. +# They're much better off being set from the control panel. diff --git a/CALCKEY.md b/CALCKEY.md index 4a85c43b4..7eb807867 100644 --- a/CALCKEY.md +++ b/CALCKEY.md @@ -9,7 +9,6 @@ - User "choices" (recommended users) like Mastodon and Soapbox - Option to publicize instance blocks - Fully revamp non-logged-in screen -- Remote follow button - Personal notes for all accounts - Non-nyaify cat mode - Timeline filters @@ -21,8 +20,8 @@ ## Work in progress - Better Messaging UI - - Videos can be played in DMs - Make your password hasn't been pwned +- Remote follow button - Admin custom CSS - Add back time machine (jump to date) - Improve accesibility score @@ -86,6 +85,7 @@ - Link hover effect - Replace all `$ts` with i18n - AVIF support +- Page drafts - Obliteration of Ai-chan - [Make showing ads optional](https://github.com/misskey-dev/misskey/pull/8996) - [Tapping avatar in mobile opens account modal](https://github.com/misskey-dev/misskey/pull/9056) diff --git a/README.md b/README.md index a5da9e1ba..5506e51a2 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@
- + Calckey logo -**🌎 **[Calckey](https://stop.voring.me/)** is an open source, decentralized social media platform that's free forever! 🚀** +**🌎 **[Calckey](https://i.calckey.cloud/)** is an open source, decentralized social media platform that's free forever! 🚀**
- +Calc (the Calckey mascot) smoking a fat dart # ✨ About Calckey @@ -33,6 +33,8 @@ # 🥂 Links +- 🚢 Flagship instance: +- 📣 Official account: - 💸 Liberapay: - 💁 Matrix support room: - 📜 Instance list: @@ -93,89 +95,17 @@ cp -r ../misskey/files . # if you don't use object storage ## 🍀 NGINX -
-Click to see an example NGINX config: - -```nginx -# Replace example.tld with your domain - -# For WebSocket -map $http_upgrade $connection_upgrade { - default upgrade; - '' close; -} - -proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache1:16m max_size=1g inactive=720m use_temp_path=off; - -server { - listen 80; - listen [::]:80; - server_name example.tld; - - # For SSL domain validation - root /var/www/html; - location /.well-known/acme-challenge/ { allow all; } - location /.well-known/pki-validation/ { allow all; } - location / { return 301 https://$server_name$request_uri; } -} - -server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name example.tld; - - ssl_session_timeout 1d; - ssl_session_cache shared:ssl_session_cache:10m; - ssl_session_tickets off; - - # To use Let's Encrypt certificate - ssl_certificate /etc/letsencrypt/live/example.tld/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/example.tld/privkey.pem; - - # To use Debian/Ubuntu's self-signed certificate (For testing or before issuing a certificate) - #ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; - #ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; - - # SSL protocol settings - ssl_protocols TLSv1.2 TLSv1.3; - ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; - ssl_prefer_server_ciphers off; - ssl_stapling on; - ssl_stapling_verify on; - - # Change to your upload limit - client_max_body_size 80m; - - # Proxy to Node - location / { - proxy_pass http://127.0.0.1:3000; - proxy_set_header Host $host; - proxy_http_version 1.1; - proxy_redirect off; - - # If it's behind another reverse proxy or CDN, remove the following. - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto https; - - # For WebSocket - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - - # Cache settings - proxy_cache cache1; - proxy_cache_lock on; - proxy_cache_use_stale updating; - add_header X-Cache $upstream_cache_status; - } -} -``` +- Run `sudo cp ./calckey.nginx.conf /etc/nginx/sites-available/ && cd /etc/nginx/sites-available/` +- Edit `calckey.nginx.conf` to reflect your instance properly +- Run `sudo cp ./calckey.nginx.conf ../sites-enabled/` +- Run `sudo nginx -t` to validate that the config is valid, then restart the NGINX service.
## 🚀 Build and launch! ### 🐢 NodeJS + #### `git pull` and run these steps to update Calckey in the future! ```sh @@ -195,19 +125,21 @@ docker up -d ### 🐳 Docker Compose ```sh -sudo docker compose build -sudo docker-compose run --rm web yarn run init -sudo docker compose up -d +docker-compose build +docker-compose run --rm web yarn run init +docker-compose up -d ``` ## 😉 Tips & Tricks -- I'd ***strongly*** recommend against using CloudFlare, but if you do, make sure to turn code minification off. +- When editing the config file, please don't fill out the settings at the bottom. They're designed *only* for managed hosting, not self hosting. Those settings are much better off being set in Calckey's control panel. +- Port 3000 (used in the default config) might be already used on your server for something else. To find an open port for Calckey, run `for p in $(seq 3000 4000); do ss -tlnH | tr -s ' ' | cut -d" " -sf4 | grep -q "${p}$" || echo "${p}"; done | head -n 1` +- I'd ***strongly*** recommend against using CloudFlare, but if you do, make sure to turn code minification off. - For push notifications, run `npx web-push generate-vapid-keys`, the put the public and private keys into Control Panel > General > ServiceWorker. - For translations, make a [DeepL](https://deepl.com) account and generate an API key, then put it into Control Panel > General > DeepL Translation. - To add another admin account: - - Go to the user's page > 3 Dots > About > Moderation > turn on "Moderator" - - Go back to Overview > click the clipboard icon next to the ID - - Run `psql -d calckey` (or whatever the database name is) - - Run `UPDATE "user" SET "isAdmin" = true WHERE id='999999';` (replace 999999 with the copied ID) - - Have the new admin log out and log back in \ No newline at end of file + - Go to the user's page > 3 Dots > About > Moderation > turn on "Moderator" + - Go back to Overview > click the clipboard icon next to the ID + - Run `psql -d calckey` (or whatever the database name is) + - Run `UPDATE "user" SET "isAdmin" = true WHERE id='999999';` (replace `999999` with the copied ID) + - Have the new admin log out and log back in diff --git a/calckey.nginx.conf b/calckey.nginx.conf new file mode 100644 index 000000000..def7fe3a5 --- /dev/null +++ b/calckey.nginx.conf @@ -0,0 +1,72 @@ +# Replace example.tld with your domain + +# For WebSocket +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache1:16m max_size=1g inactive=720m use_temp_path=off; + +server { + listen 80; + listen [::]:80; + server_name example.tld; + + # For SSL domain validation + root /var/www/html; + location /.well-known/acme-challenge/ { allow all; } + location /.well-known/pki-validation/ { allow all; } + location / { return 301 https://$server_name$request_uri; } +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name example.tld; + + ssl_session_timeout 1d; + ssl_session_cache shared:ssl_session_cache:10m; + ssl_session_tickets off; + + # To use Let's Encrypt certificate + ssl_certificate /etc/letsencrypt/live/example.tld/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/example.tld/privkey.pem; + + # To use Debian/Ubuntu's self-signed certificate (For testing or before issuing a certificate) + #ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; + #ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; + + # SSL protocol settings + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; + ssl_prefer_server_ciphers off; + ssl_stapling on; + ssl_stapling_verify on; + + # Change to your upload limit + client_max_body_size 80m; + + # Proxy to Node + location / { + proxy_pass http://127.0.0.1:3000; + proxy_set_header Host $host; + proxy_http_version 1.1; + proxy_redirect off; + + # If it's behind another reverse proxy or CDN, remove the following. + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + + # For WebSocket + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + # Cache settings + proxy_cache cache1; + proxy_cache_lock on; + proxy_cache_use_stale updating; + add_header X-Cache $upstream_cache_status; + } +} diff --git a/locales/en-US.yml b/locales/en-US.yml index f5758ed64..e9867f523 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -159,7 +159,7 @@ proxyAccount: "Proxy account" proxyAccountDescription: "A proxy account is an account that acts as a remote follower for users under certain conditions. For example, when a user adds a remote user to the list, the remote user's activity will not be delivered to the instance if no local user is following that user, so the proxy account will follow instead." host: "Host" selectUser: "Select a user" -recipient: "Recipient" +recipient: "Recipient(s)" annotation: "Comments" federation: "Federation" instances: "Instances" @@ -770,8 +770,8 @@ noBotProtectionWarning: "Bot protection is not configured." configure: "Configure" postToGallery: "Create new gallery post" gallery: "Gallery" -recentPosts: "Recent posts" -popularPosts: "Popular posts" +recentPosts: "Recent pages" +popularPosts: "Popular pages" shareWithNote: "Share with note" ads: "Advertisements" expiration: "Deadline" @@ -1094,7 +1094,7 @@ _channel: usersCount: "{n} Participants" notesCount: "{n} Notes" _messaging: - dms: "DMs" + dms: "Private" groups: "Groups" _menuDisplay: sideFull: "Side" @@ -1264,10 +1264,10 @@ _permissions: "read:reactions": "View your reactions" "write:reactions": "Edit your reactions" "write:votes": "Vote on a poll" - "read:pages": "View your pages" - "write:pages": "Edit or delete your pages" - "read:page-likes": "View your likes on pages" - "write:page-likes": "Edit your likes on pages" + "read:pages": "View your page" + "write:pages": "Edit or delete your page" + "read:page-likes": "View your likes on page" + "write:page-likes": "Edit your likes on page" "read:user-groups": "View your user groups" "write:user-groups": "Edit or delete your user groups" "read:channels": "View your channels" @@ -1441,7 +1441,7 @@ _pages: liked: "Liked Pages" featured: "Popular" inspector: "Inspector" - contents: "Contents" + contents: "Content" content: "Page block" variables: "Variables" title: "Title" diff --git a/package.json b/package.json index 85e12bfb4..4827b5e07 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "calckey", - "version": "12.119.0-calc.14", + "version": "12.119.0-calc.15", "codename": "aqua", "repository": { "type": "git", "url": "https://codeberg.org/thatonecalculator/calckey.git" }, - "packageManager": "yarn@3.2.4", + "packageManager": "yarn@3.3.0", "workspaces": [ "packages/client", "packages/backend", @@ -39,10 +39,10 @@ "lodash": "^4.17.21" }, "dependencies": { - "@bull-board/api": "^4.6.3", - "@bull-board/ui": "^4.6.3", + "@bull-board/api": "^4.6.4", + "@bull-board/ui": "^4.6.4", "@tensorflow/tfjs": "^3.21.0", - "eslint": "^8.27.0", + "eslint": "^8.28.0", "execa": "5.1.1", "gulp": "4.0.2", "gulp-cssnano": "2.1.3", @@ -55,13 +55,13 @@ "seedrandom": "^3.0.5" }, "devDependencies": { - "@types/gulp": "4.0.9", + "@types/gulp": "4.0.10", "@types/gulp-rename": "2.0.1", - "@typescript-eslint/parser": "5.42.1", + "@typescript-eslint/parser": "5.43.0", "cross-env": "7.0.3", "cypress": "10.11.0", "start-server-and-test": "1.14.0", - "typescript": "4.8.4", + "typescript": "4.9.3", "vue-eslint-parser": "^9.1.0" } } diff --git a/packages/backend/migration/1668828368510PageDraft.js b/packages/backend/migration/1668828368510PageDraft.js new file mode 100644 index 000000000..4a6818912 --- /dev/null +++ b/packages/backend/migration/1668828368510PageDraft.js @@ -0,0 +1,8 @@ +export class Page1668828368510 { + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "page" ADD "isPublic" boolean NOT NULL DEFAULT true`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "page" DROP COLUMN "isPublic"`); + } +} diff --git a/packages/backend/migration/1668831378728FixCalckeyAgain.js b/packages/backend/migration/1668831378728FixCalckeyAgain.js new file mode 100644 index 000000000..d5e67a48c --- /dev/null +++ b/packages/backend/migration/1668831378728FixCalckeyAgain.js @@ -0,0 +1,11 @@ +export class FixCalckeyAgain1668831378728 { + name = 'FixCalckeyAgain1668831378728' + + async up(queryRunner) { + await queryRunner.query(`UPDATE "meta" SET "useStarForReactionFallback" = TRUE`); + } + + async down(queryRunner) { + await queryRunner.query(`UPDATE "meta" SET "useStarForReactionFallback" = FALSE`); + } +} diff --git a/packages/backend/package.json b/packages/backend/package.json index 190d57ff7..52c83be0c 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -21,9 +21,9 @@ "@tensorflow/tfjs-node": "3.21.1" }, "dependencies": { - "@bull-board/api": "^4.6.3", - "@bull-board/koa": "^4.6.3", - "@bull-board/ui": "^4.6.3", + "@bull-board/api": "^4.6.4", + "@bull-board/koa": "^4.6.4", + "@bull-board/ui": "^4.6.4", "@discordapp/twemoji": "14.0.2", "@elastic/elasticsearch": "7.17.0", "@koa/cors": "3.4.3", @@ -32,15 +32,15 @@ "@peertube/http-signature": "1.7.0", "@sinonjs/fake-timers": "9.1.2", "@syuilo/aiscript": "0.11.1", - "ajv": "8.11.0", + "ajv": "8.11.2", "archiver": "5.3.1", "autobind-decorator": "2.4.0", "autwh": "0.1.0", - "aws-sdk": "2.1253.0", + "aws-sdk": "2.1258.0", "bcryptjs": "2.4.3", "blurhash": "1.1.5", "bull": "4.10.1", - "cacheable-lookup": "6.1.0", + "cacheable-lookup": "7.0.0", "cbor": "8.1.0", "chalk": "5.1.2", "chalk-template": "0.4.0", @@ -54,10 +54,10 @@ "feed": "4.2.2", "file-type": "17.1.6", "fluent-ffmpeg": "2.1.2", - "got": "12.5.2", + "got": "12.5.3", "hpagent": "0.1.2", "ioredis": "4.28.5", - "ip-cidr": "3.0.10", + "ip-cidr": "3.0.11", "is-svg": "4.3.2", "js-yaml": "4.1.0", "jsdom": "20.0.2", @@ -83,7 +83,7 @@ "node-fetch": "3.3.0", "nodemailer": "6.8.0", "nsfwjs": "2.4.2", - "oauth": "^0.9.15", + "oauth": "^0.10.0", "os-utils": "0.0.14", "parse5": "7.1.1", "pg": "8.8.0", @@ -111,7 +111,7 @@ "stringz": "2.1.0", "summaly": "2.7.0", "syslog-pro": "1.0.0", - "systeminformation": "5.12.14", + "systeminformation": "5.13.5", "tesseract.js": "^3.0.3", "tinycolor2": "1.4.2", "tmp": "0.2.1", @@ -130,7 +130,7 @@ "xev": "3.0.2" }, "devDependencies": { - "@redocly/openapi-core": "1.0.0-beta.112", + "@redocly/openapi-core": "1.0.0-beta.114", "@types/bcryptjs": "2.4.2", "@types/bull": "3.15.9", "@types/cbor": "6.0.0", @@ -165,7 +165,7 @@ "@types/rename": "1.0.4", "@types/sanitize-html": "2.6.2", "@types/semver": "7.3.13", - "@types/sharp": "0.30.5", + "@types/sharp": "0.31.0", "@types/sinonjs__fake-timers": "8.1.2", "@types/speakeasy": "2.0.7", "@types/tinycolor2": "1.4.3", @@ -174,12 +174,12 @@ "@types/web-push": "3.3.2", "@types/websocket": "1.0.5", "@types/ws": "8.5.3", - "@typescript-eslint/eslint-plugin": "5.42.1", - "@typescript-eslint/parser": "5.42.1", + "@typescript-eslint/eslint-plugin": "5.43.0", + "@typescript-eslint/parser": "5.43.0", "cross-env": "7.0.3", - "eslint": "8.27.0", + "eslint": "8.28.0", "eslint-plugin-import": "2.26.0", "execa": "6.1.0", - "typescript": "4.8.4" + "typescript": "4.9.3" } } diff --git a/packages/backend/src/misc/clone.ts b/packages/backend/src/misc/clone.ts new file mode 100644 index 000000000..16fad2412 --- /dev/null +++ b/packages/backend/src/misc/clone.ts @@ -0,0 +1,18 @@ +// structredCloneが遅いため +// SEE: http://var.blog.jp/archives/86038606.html + +type Cloneable = string | number | boolean | null | { [key: string]: Cloneable } | Cloneable[]; + +export function deepClone(x: T): T { + if (typeof x === 'object') { + if (x === null) return x; + if (Array.isArray(x)) return x.map(deepClone) as T; + const obj = {} as Record; + for (const [k, v] of Object.entries(x)) { + obj[k] = deepClone(v); + } + return obj as T; + } else { + return x; + } +} diff --git a/packages/backend/src/models/entities/page.ts b/packages/backend/src/models/entities/page.ts index baad3a36f..fac59479e 100644 --- a/packages/backend/src/models/entities/page.ts +++ b/packages/backend/src/models/entities/page.ts @@ -40,6 +40,9 @@ export class Page { @Column('boolean') public alignCenter: boolean; + @Column('boolean') + public isPublic: boolean; + @Column('boolean', { default: false, }) diff --git a/packages/backend/src/models/repositories/drive-file.ts b/packages/backend/src/models/repositories/drive-file.ts index 4366b02cc..a01fd86c6 100644 --- a/packages/backend/src/models/repositories/drive-file.ts +++ b/packages/backend/src/models/repositories/drive-file.ts @@ -9,6 +9,8 @@ import { query, appendQuery } from '@/prelude/url.js'; import { Meta } from '@/models/entities/meta.js'; import { fetchMeta } from '@/misc/fetch-meta.js'; import { Users, DriveFolders } from '../index.js'; +import { deepClone } from '@/misc/clone.js'; + type PackOptions = { detail?: boolean, @@ -29,9 +31,7 @@ export const DriveFileRepository = db.getRepository(DriveFile).extend({ getPublicProperties(file: DriveFile): DriveFile['properties'] { if (file.properties.orientation != null) { - // TODO - //const properties = structuredClone(file.properties); - const properties = JSON.parse(JSON.stringify(file.properties)); + const properties = deepClone(file.properties); if (file.properties.orientation >= 5) { [properties.width, properties.height] = [properties.height, properties.width]; } diff --git a/packages/backend/src/models/repositories/page.ts b/packages/backend/src/models/repositories/page.ts index 092b26b39..65b54f8b8 100644 --- a/packages/backend/src/models/repositories/page.ts +++ b/packages/backend/src/models/repositories/page.ts @@ -65,6 +65,7 @@ export const PageRepository = db.getRepository(Page).extend({ content: page.content, variables: page.variables, title: page.title, + isPublic: page.isPublic, name: page.name, summary: page.summary, hideTitleWhenPinned: page.hideTitleWhenPinned, diff --git a/packages/backend/src/models/schema/page.ts b/packages/backend/src/models/schema/page.ts index 55ba3ce7f..19074947b 100644 --- a/packages/backend/src/models/schema/page.ts +++ b/packages/backend/src/models/schema/page.ts @@ -47,5 +47,9 @@ export const packedPageSchema = { ref: 'UserLite', optional: false, nullable: false, }, + isPublic: { + type: 'boolean', + optional: false, nullable: false, + }, }, } as const; diff --git a/packages/backend/src/server/api/endpoints/pages/create.ts b/packages/backend/src/server/api/endpoints/pages/create.ts index e7b78fb38..063faf6ec 100644 --- a/packages/backend/src/server/api/endpoints/pages/create.ts +++ b/packages/backend/src/server/api/endpoints/pages/create.ts @@ -53,6 +53,7 @@ export const paramDef = { eyeCatchingImageId: { type: 'string', format: 'misskey:id', nullable: true }, font: { type: 'string', enum: ['serif', 'sans-serif'], default: 'sans-serif' }, alignCenter: { type: 'boolean', default: false }, + isPublic: { type: 'boolean', default: true }, hideTitleWhenPinned: { type: 'boolean', default: false }, }, required: ['title', 'name', 'content', 'variables', 'script'], @@ -97,6 +98,7 @@ export default define(meta, paramDef, async (ps, user) => { alignCenter: ps.alignCenter, hideTitleWhenPinned: ps.hideTitleWhenPinned, font: ps.font, + isPublic: ps.isPublic, })).then(x => Pages.findOneByOrFail(x.identifiers[0])); return await Pages.pack(page); diff --git a/packages/backend/src/server/api/endpoints/pages/show.ts b/packages/backend/src/server/api/endpoints/pages/show.ts index 54ae43deb..384975af7 100644 --- a/packages/backend/src/server/api/endpoints/pages/show.ts +++ b/packages/backend/src/server/api/endpoints/pages/show.ts @@ -67,5 +67,9 @@ export default define(meta, paramDef, async (ps, user) => { throw new ApiError(meta.errors.noSuchPage); } + if (!page.isPublic && (user == null || (page.userId !== user.id))) { + throw new ApiError(meta.errors.noSuchPage); + } + return await Pages.pack(page, user); }); diff --git a/packages/backend/src/server/api/endpoints/pages/update.ts b/packages/backend/src/server/api/endpoints/pages/update.ts index 8230ea09b..585e9e73e 100644 --- a/packages/backend/src/server/api/endpoints/pages/update.ts +++ b/packages/backend/src/server/api/endpoints/pages/update.ts @@ -60,6 +60,7 @@ export const paramDef = { font: { type: 'string', enum: ['serif', 'sans-serif'] }, alignCenter: { type: 'boolean' }, hideTitleWhenPinned: { type: 'boolean' }, + isPublic: { type: 'boolean' }, }, required: ['pageId', 'title', 'name', 'content', 'variables', 'script'], } as const; @@ -104,6 +105,7 @@ export default define(meta, paramDef, async (ps, user) => { content: ps.content, variables: ps.variables, script: ps.script, + isPublic: ps.isPublic, alignCenter: ps.alignCenter === undefined ? page.alignCenter : ps.alignCenter, hideTitleWhenPinned: ps.hideTitleWhenPinned === undefined ? page.hideTitleWhenPinned : ps.hideTitleWhenPinned, font: ps.font === undefined ? page.font : ps.font, diff --git a/packages/backend/src/server/api/endpoints/users/pages.ts b/packages/backend/src/server/api/endpoints/users/pages.ts index e1d876e6b..b76071264 100644 --- a/packages/backend/src/server/api/endpoints/users/pages.ts +++ b/packages/backend/src/server/api/endpoints/users/pages.ts @@ -34,7 +34,8 @@ export const paramDef = { export default define(meta, paramDef, async (ps, user) => { const query = makePaginationQuery(Pages.createQueryBuilder('page'), ps.sinceId, ps.untilId) .andWhere('page.userId = :userId', { userId: ps.userId }) - .andWhere('page.visibility = \'public\''); + .andWhere('page.visibility = \'public\'') + .andWhere('page.isPublic = true'); const pages = await query .take(ps.limit) diff --git a/packages/client/package.json b/packages/client/package.json index cd333c34d..bc49ac021 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -19,8 +19,8 @@ "blurhash": "1.1.5", "broadcast-channel": "4.18.1", "browser-image-resizer": "https://github.com/misskey-dev/browser-image-resizer.git#commit=0380d12c8e736788ea7f4e6e985175521ea7b23c", - "chart.js": "3.9.1", - "chartjs-adapter-date-fns": "2.0.0", + "chart.js": "4.0.1", + "chartjs-adapter-date-fns": "2.0.1", "chartjs-plugin-gradient": "0.5.1", "chartjs-plugin-zoom": "1.2.1", "compare-versions": "5.0.1", @@ -31,7 +31,7 @@ "idb-keyval": "6.2.0", "insert-text-at-cursor": "0.3.0", "json5": "2.2.1", - "katex": "0.15.6", + "katex": "0.16.3", "matter-js": "0.18.0", "mfm-js": "0.23.0", "misskey-js": "0.0.14", @@ -48,16 +48,16 @@ "swiper": "^8.4.4", "syuilo-password-strength": "0.0.1", "textarea-caret": "3.1.0", - "three": "0.144.0", + "three": "0.146.0", "throttle-debounce": "5.0.0", "tinycolor2": "1.4.2", "tsc-alias": "1.7.1", "tsconfig-paths": "4.1.0", "twemoji-parser": "14.0.0", - "typescript": "4.8.4", + "typescript": "4.9.3", "uuid": "9.0.0", "vanilla-tilt": "1.7.3", - "vite": "^3.2.3", + "vite": "^3.2.4", "vue": "3.2.45", "vue-isyourpasswordsafe": "^2.0.0", "vue-plyr": "^7.0.0", @@ -67,7 +67,7 @@ "devDependencies": { "@types/escape-regexp": "0.0.1", "@types/glob": "8.0.0", - "@types/gulp": "4.0.9", + "@types/gulp": "4.0.10", "@types/gulp-rename": "2.0.1", "@types/katex": "0.14.0", "@types/matter-js": "0.18.2", @@ -76,11 +76,11 @@ "@types/throttle-debounce": "5.0.0", "@types/tinycolor2": "1.4.3", "@types/uuid": "8.3.4", - "@typescript-eslint/eslint-plugin": "5.42.1", - "@typescript-eslint/parser": "5.42.1", + "@typescript-eslint/eslint-plugin": "5.43.0", + "@typescript-eslint/parser": "5.43.0", "cross-env": "7.0.3", "cypress": "10.11.0", - "eslint": "8.27.0", + "eslint": "8.28.0", "eslint-plugin-import": "2.26.0", "eslint-plugin-vue": "9.7.0", "rollup": "2.79.1", diff --git a/packages/client/src/components/MkDialog.vue b/packages/client/src/components/MkDialog.vue index 14e33db5f..e01b0a332 100644 --- a/packages/client/src/components/MkDialog.vue +++ b/packages/client/src/components/MkDialog.vue @@ -33,7 +33,7 @@ {{ i18n.ts.cancel }}
- {{ (showCancelButton || input || select) ? i18n.ts.ok : i18n.ts.yes }} + {{ i18n.ts.yes }} {{ i18n.ts.no }}
diff --git a/packages/client/src/components/MkFollowButton.vue b/packages/client/src/components/MkFollowButton.vue index a2ba06faf..6fd5ccb1c 100644 --- a/packages/client/src/components/MkFollowButton.vue +++ b/packages/client/src/components/MkFollowButton.vue @@ -1,5 +1,6 @@ -