Add /arubinosky

This commit is contained in:
2025-01-08 01:30:14 +09:00
parent da36d8ef31
commit 759228e3a1
31 changed files with 2961 additions and 34 deletions

View File

@@ -3,9 +3,8 @@ import "../app.css";
import "./webfont.css";
import { page } from "$app/state";
import Seo, { defaultSeo, mergeSeo } from "$components/seo";
import { PUBLIC_WEB_DOMAIN } from "$env/static/public";
import { defaultSeo, mergeSeo } from "$lib/common/seo";
import SvelteSeo from "svelte-seo";
let { children } = $props();
let seo = $derived.by(() =>
@@ -18,6 +17,6 @@ let seo = $derived.by(() =>
);
</script>
<SvelteSeo {...seo} />
<Seo {...seo} />
{@render children()}

View File

@@ -0,0 +1,31 @@
import { type RequestEvent, text } from "@sveltejs/kit";
import { RateLimiter } from "sveltekit-rate-limiter/server";
import { dev } from "$app/environment";
import { MISSKEY_API_KEY } from "$env/static/private";
import { api } from "misskey-js";
const limiter = new RateLimiter({
IP: [10, "d"], // IP address limiter
IPUA: [5, "10m"], // IP + User Agent limiter
});
const misskey = new api.APIClient({
origin: "https://misskey.cannorin.net",
credential: MISSKEY_API_KEY,
});
export async function GET(event: RequestEvent) {
if (!dev && (await limiter.isLimited(event)))
return new Response("Too many requests", { status: 429 });
const invites = await misskey.request("admin/invite/list", {
type: "unused",
sort: "+createdAt",
limit: 10,
});
const invite = invites.find((x) => !x.createdBy && !x.usedAt);
if (invite) return text(invite.code);
return new Response("Not found", { status: 404 });
}

View File

@@ -0,0 +1,13 @@
<script lang="ts">
import "./theme.css";
let { children } = $props();
$effect.pre(() => {
const icon: HTMLLinkElement | null =
document.querySelector("link[rel~='icon']");
if (icon) icon.href = "/favicon2.png";
});
</script>
{@render children()}

View File

@@ -0,0 +1,117 @@
<script lang="ts">
import CharaSad from "$assets/images/static/arubinosky/arubinochan-scared.svg?component";
import Chara from "$assets/images/static/arubinosky/arubinochan.svg?component";
import Logo from "$assets/images/static/arubinosky/logo.svg?component";
import { limitWidth } from "$lib/constants";
import { cn } from "$lib/utils";
import Embed from "./embed.svelte";
import Terms from "./terms.md";
import Check from "lucide-svelte/icons/check";
import Copy from "lucide-svelte/icons/copy";
const getInviteCode = async () => {
copied = false;
const res = await fetch("/api/misskey/invite-code");
if (res.ok)
return {
type: "ok" as const,
code: await res.text(),
};
if (res.status === 429) return { type: "rate-limited" as const };
if (res.status === 404) return { type: "closed" as const };
return { type: "unknown-error" as const };
};
let invite = $state<Awaited<ReturnType<typeof getInviteCode>> | undefined>();
let copied = $state(false);
</script>
<main class={cn(limitWidth, "flex grow flex-col items-center gap-10 py-8")}>
<h1>
<a href="https://misskey.cannorin.net/" target="_blank">
<Logo class="w-full h-auto" role="presentation" />
<span class="sr-only">あるびのすきー</span>
</a>
</h1>
<section id="about" class="prose !w-full !min-w-full sect">
<h2>あるびのすきーとは?</h2>
<p>
あるびのすきーは「シンプル」と「かわいい」をテーマにした <a href="https://misskey-hub.net/ja/" target="_blank">Misskey</a> インスタンスです。
</p>
<ul>
<li>UIがかわいい マスコットキャラもかわいい!</li>
<li>与謝野晶子もレターパックもいません!(外部からは飛んでくるかも)</li>
<li>好き勝手に話す bot がいます! 話しかけてあげてね!</li>
</ul>
<Embed />
↓登録は利用規約を読んでから!↓
</section>
<section id="terms" class="prose !w-full !min-w-full sect">
<Terms />
</section>
<section id="invite" class="sect flex flex-col-reverse md:flex-row gap-6 items-center justify-center">
<div class="flex flex-col gap-4 items-center pb-6 md:pb-0">
<h2 class="text-xl font-bold">招待コードを取得しよう!</h2>
{#if !invite}
<button
class="border-2 rounded px-8 py-2 w-fit"
onclick={async () => { invite = await getInviteCode() }}>
今すぐ取得!
</button>
{:else if invite.type === "ok"}
{@const code = invite.code}
<div class="flex flex-col items-center gap-4">
あなたの招待コードは
<div class="flex flex-nowrap items-center justify-between h-8 gap-2 border-2 rounded px-2">
<code>{code}</code>
<button title="コピー" onclick={() => { navigator.clipboard.writeText(code); copied = true; }} class="text-xs">
{#if copied}
<Check size={18} aria-label="コピーしました" />
{:else}
<Copy size={18} aria-label="コピー" />
{/if}
</button>
</div>
</div>
<a href="https://misskey.cannorin.net/" target="_blank" class="border-2 rounded px-8 py-2 w-fit">
今すぐ登録!
</a>
{:else if invite.type === "rate-limited"}
<div>
<p>取得ボタンを押しすぎです。</p>
<p>しばらく経ってからやり直してね</p>
</div>
{:else if invite.type === "closed"}
<p>ごめんなさい、アカウントの枠がないようです。。</p>
{:else if invite.type === "unknown-error"}
<div>
<p>謎のエラーが起こっています!!</p>
<p>管理者までご連絡ください。。</p>
</div>
{/if}
</div>
{#if !invite || invite.type === "ok"}
<Chara class="max-w-[400px]" />
{:else}
<CharaSad class="max-w-[400px]" />
{/if}
</section>
</main>
<style lang="postcss">
.sect {
@apply w-full rounded-xl p-6;
background-color: white;
}
</style>

View File

@@ -0,0 +1,4 @@
<div class="h-[400px] max-h-[400px] mb-4">
<iframe title="@arubinochan のノート" src="https://misskey.cannorin.net/embed/user-timeline/a2a1hq322ylv002q?maxHeight=400&colorMode=light" data-misskey-embed-id="v1_1e08df2d-16a0-4d94-94bc-8d858f37d6e0" loading="lazy" referrerpolicy="strict-origin-when-cross-origin" style="border: none; width: 100%; max-width: 500px; height: 300px; color-scheme: light dark;"></iframe>
<script defer src="https://misskey.cannorin.net/embed.js"></script>
</div>

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import Logo from "$assets/images/static/arubinosky/logo.svg?component";
import { limitWidth } from "$lib/constants";
import { cn } from "$lib/utils";
import Policy from "./policy.md";
</script>
<main class={cn(limitWidth, "flex grow flex-col items-center gap-10 py-8")}>
<h1>
<a href="/arubinosky">
<Logo class="w-full h-auto" role="presentation" />
<span class="sr-only">あるびのすきー</span>
</a>
</h1>
<section class="prose prose-sm !w-full !min-w-full rounded-xl p-6 bg-white">
<Policy />
</section>
</main>

View File

@@ -0,0 +1,76 @@
## プライバシーポリシー
本サービスを利用することにつき、利用者は管理者の定める本規定に同意したものとみなします。
### 第一条 個人情報の適用
個人情報とは、個人情報保護法に言う「個人情報」を指すものとし、生存する個人に関する情報であって、当該情報に含まれる氏名、生年月日、連絡先、その他の記述などにより特定の個人を識別できる情報及び個人識別情報を指します。
### 第二条 個人情報の収集方法
* 管理者はユーザーが利用登録をする際に、メールアドレスをお尋ねします。
* サービスの利用履歴、IP アドレス、ASN 等が本サービスのサーバーに記録されます。
* サービスの利用に伴ってユーザーによって生成された各種コンテンツについては、本サービスのサーバーに保存され、処理されます。本サービスの性質上、それらのコンテンツは第三者が管理する類似のサービスMastodon や Misskey などの別インスタンス)に配信されることがあります。本サービスはそれらのコンテンツの閲覧を、ユーザがコンテンツの公開範囲によって許可した者に限定するよう誠意を持って努めます。しかし、第三者サービスにおいても同様に扱われるとは限りません。
### 第三条 個人情報を収集・利用する目的
管理者が個人情報を収集・利用する目的は以下の通りです。
* ユーザーにサービスを提供するため。
* サービスの運営を維持するため。
* ユーザーからのお問い合わせに回答するため(パスワードリセットやアカウント消去処理も含む)。
* メンテナンス・サービスに関する重要なお知らせを通達するため。
* ユーザーがご自身の登録情報の開示請求や変更請求、消去などを行った際に確認を行っていただくため。
* その他上記の利用目的に付随する目的。
### 第四条 個人情報の第三者提供
1. 管理者は、以下の場合を除き、ユーザーの同意を得ずに個人情報を第三者に提供することはありません。
1. 児童買春や児童ポルノに関連する行為の規制・処罰、児童の保護が必要と判断される場合、または売春、違法薬物、臓器売買、違法物品の売買が投稿内容や行動から明らかに推測される場合。
2. 国の機関や地方公共団体、またはその委託を受けた機関が法令に基づく事務を遂行することに対して管理者が協力する必要があり、ユーザーの同意を得ることで支障が生じる場合。
2. 以下のような場合は、前項のいう第三者には該当しないものといたします。
1. 管理者が本サービスの運営・管理に必要な範囲内で、個人情報の取り扱いを委託する場合(例: Cloudflare、Oracle Cloud、Wasabi 等のクラウドサービス提供者)。
2. サービス運営の継承に伴い、個人情報が提供される場合。
3. 第二条で述べたような、ユーザー生成コンテンツが第三者サービスに配信される場合、ユーザーがコンテンツの公開範囲を設定する行為をもって、その公開範囲によって指定される第三者に対して、コンテンツに含まれうる個人情報の提供を許可するものとします。
### 第五条 本人個人情報の開示・訂正・消去・利用停止等
1. 管理者は、本人から個人情報の開示を求められた場合、可能な限り迅速に対応します。ただし、以下の場合には部分的な開示または開示拒否を行う場合があります。この際は理由を明記した通知を送付します。
* 本人または第三者の生命、身体、財産的権利利益を害するおそれがある場合。
* 管理者の運営に著しい支障を及ぼすおそれがある場合。
* 法令違反となる場合。
なお、履歴情報及び運営上特性のある個人情報に該当しない情報に関しては原則として開示しないものとします。
2. ユーザーは、管理者の保有する自己の個人情報に誤りがある場合、パスワードリセットや登録情報の修正などの手段を通じて訂正・追加・消去を請求できます。管理者は必要に応じて速やかに対応を行い、以下の場合には通知を送付します。
* パスワードの変更が行われた場合。
* アカウントの消去が行われた場合。
3. 管理者は、以下の理由により個人情報の利用停止または消去を求められた場合、調査を行い必要な対応を取ります。
* 利用目的を超えた個人情報の取り扱い。
* 不正な手段による個人情報の収集・利用。
調査結果に基づき、利用停止等を実施または請求不可の理由を通知します。なお、利用停止等が困難であると判断され、ユーザーの権利・利益を保護するために必要な代替手段を講じられる場合は、これをもって対処することとします。
4. ユーザー生成コンテンツに含まれる個人情報のうち、第二条で述べたような、第三者による類似サービスに配信されたものについては、管理者は本サービスが直接管理可能な範囲内でのみ責任を負うものとします。配信先の第三者サービスが保有・処理する個人情報に関しては、当該第三者のポリシーが適用されるため、管理者はその取り扱いについて責任を負いません。
### 第六条 プライバシーポリシーの改定
1. 管理者は法令と以下に定める場合を除き、本ポリシーの内容をいつでも必要に応じて改定することができます。
- 管理者が本ポリシーの内容のうち、第三条で定める個人情報の利用目的を改定する際、改定後の利用目的が改定前と関連性を有すると合理的に認められる場合に限定して行うものとします。
2. 改定が行われた場合、管理者はウェブサイト上の告知、またはサービス内通知を通じてユーザーに可能な限り迅速に周知します。
3. 管理者が別途定める場合を除いて、変更後のプライバシーポリシーは本ウェブサイト、ないし当該規約ページに掲載した時から効力を生じるものとします。
### 問い合わせ連絡先
本ポリシーに関する問い合わせは下記のEメールアドレスにお願いします。
contact@cannorin.net
### 付則
制定日
2025 年 01 月 08 日 初版発行

View File

@@ -0,0 +1,142 @@
## 利用規約
<aside class="text-xs text-muted-foreground">
この利用規約の内容は、hota さんが運営する Mastodon インスタンスの <a href="https://wiki.maud.io/ja/mastodon/about" target="_blank">:don: 利用規約</a> を元にしています!
</aside>
### はじめに
まずは [プライバシーポリシー](/arubinosky/policy) をご確認ください。Misskey インスタンスに参加する際に、ユーザーのみなさまに一般的に同意してほしいことが書かれています。
この利用規約には、みなさまに同意してほしい・守ってほしい規約で **このサーバーに特有のもの** を書いています。
あるびのすきーに参加いただく前に、必ず読んでください。
### おことわり
* 当サーバーのサービスは無償かつ無保証にて提供されます。
- 例えば、管理者が寝ている間の障害発生には対応できません。
* 管理者は予告なく一時的なサービス停止を伴うメンテナンスを行うことがあります。
- 極力予告する予定ですが、停止したら <a href="https://misskey.cannorin.net/@admin" target="_blank">@admin</a> が事後報告するはずです。
* 管理者はこの規約をいつでも必要に応じて改定することができますが、利用者にはその都度必ず告知を行うものとします。
- 基本的に Misskey のお知らせ機能を使います。
### アカウントの作成
ここでは、アカウントの作成にあたって必要なことを説明しています。少々長いかもしれませんが、きちんと読んでください。
* **事前にこの規約を読んでください**
- 当サーバーへの登録が完了した時点で、あなたはこの規約をよく読み、これに同意したものとみなされます。
* **アカウントを作成できないことがあります**
- 当サーバーは現在手探りで運用しているので、登録を「半開放式」にしています。
具体的には、作成可能なアカウントの総数を制限しています。
- 作成可能なアカウントの枠が余っている場合のみ、このページから招待コードを取得し、それを使ってアカウントを作成することができます。
枠が上限に達している場合、アカウントを作成できません。ごめんなさい!
- アカウントの枠は、ユーザーがもう少し増えてもサーバーがパンクしなさそうだなぁと管理者が判断したタイミングで追加されます。
* **アカウントは原則一人一個でお願いします**
- 上記の通りアカウントの枠に限りがあるので、当面の間アカウントは一人につき一個でお願いします。
- 何か特別な事情があってサブアカウントを作りたい際は、<a href="https://misskey.cannorin.net/@admin" target="_blank">@admin</a> までご相談くだされば、審査の上で招待コードを発行できるかもしれません。ただし、最低でも以下の条件を満たしている必要があります。
- メインのアカウントがアクティブな利用者である
- メインのアカウントとは全く異なる用途で使う(単に鍵垢が欲しいとかはダメです)
- 特に許可を取ってないのにサブ垢っぽいな~と思われるアカウントは警告の上で削除することがあります。あまりに悪質な場合はメインアカウントも処分の対象になります。
* **有効なメールアドレスを使用してください**
- 「捨てアド」などの一時的なメールアドレスを用いたアカウント作成は認められていません。
- 一部のドメインはブラックリストに登録されており、アカウントの新規作成には使用できなくなっています。
### 禁止行為
当サーバーで禁止される行為の一例を以下に示します。ここに無いことは大丈夫、という意味ではないです。
* 宣伝・広告のみを目的としたアカウントの作成
* 国内法に反する行為やそれを唆す内容の投稿
- 管理者は法律の専門家 *ではない* ことに注意してください。
* 有害なリンクの投稿
- 出会い系や明確なスパム/フィッシングサイトなどが主ですが、個別に判断します。
* ユーザーとサーバーに対して迷惑のかかる行為の一切
- 例1: 相手に通知を送信させることを目的としたアクション(フォロー/リアクション/リノート/返信)を繰り返す
- 例2: 購読を主な目的としない無差別での大量フォローを行う
* 差別的発言等、特定の相手を傷つける目的を持ってなされる言動
* 使い捨てのメールアドレスなど、連絡先として疎通不可能な手段を用いて登録すること
* アカウントの譲渡、売買
- 金銭の授受が発生しない譲渡に限り、特別な事情のある場合は事前にご一報ください。
* **ここに無いルールを勝手に作って他者に押し付けないこと**
- 最終的な判断は管理者によって行われます。
### 通報について
上で掲げた禁止行為に抵触していると考えられる行為や、それ以外でも問題があると思われる投稿・ユーザーについての通報を受け付けています。
常にサーバーとタイムラインを監視しているわけではないので、基本的に通報があったものを優先して対処しています。
通報に関しては以下の項目を明確にしてください。記載がないものは処理の対象とされません。
- ノート単体、投稿内容に問題があるのか
- ユーザー自体、不審なアクティビティなどに問題があるのか
- どのような影響、問題があるのか
- 当事者間による解決はできなかったのか
- (サーバーへの迷惑行為など、客観的判断が可能な内容についてのみ)どのような処置が適していると考えるか
通報を受けた投稿は対象ユーザーに対してメールで警告する際に示されることがあります。
しかし、該当する投稿が特定個人とのやり取りなど、開示にあたり **通報者に不利益や危害が及ぶおそれのある場合** については、これを開示することはありません。
原則として、通報を行ったユーザーに対してその結果を案内することはありません。
また、個々の案件がその後どうなったかについての問い合わせも受け付けていません。
ただし、[プライバシーポリシー](/arubinosky/policy) で定める場合は除きます。
### 処置について
当規約に反すると管理者が判断した投稿/ユーザーに対しては、下記に定める処置を予告なく実施することがあります。
* 当サーバーのユーザー
- 本人へのメールでの警告
- 該当する投稿の管理者削除
- サイレンス(公開タイムラインへの非表示)
- ログイン停止
- アカウント停止
- IP によるアクセス制限
* 外部サーバーのユーザー
- サイレンス
- 停止(当サーバー上からの抹消)
個別の判断理由について、処置時のメールによる通告以上の詳細を問い合わせによって開示することはありません。
またサーバーの処理上不可逆なものが多いため、**原則として処置が覆ることはありません。**
<!--
### Bot アカウントについて
当サーバーでは原則として禁止はしていませんが、以下に示す追加の Bot 運用ルールに従う必要があります。
#### Botの定義
* プログラムなどの手段により当サーバーの提供するAPIを利用し、自動化された操作を行うものを以下 **Botプログラム** と呼称します。
* Botプログラムを用いた操作を主とするアカウントを以下 **Botアカウント** と呼称します。
* Botプログラムには、Twitterなど他のSNS/マイクロブログにおける特定のユーザーによる投稿本文を当サーバー上のアカウントを用いて逐一 **再投稿(ミラー/擬似的な同時投稿)する** ものを含みます。
#### 運用ルール
* このページで定めている他のルールについても守ること
* プロフィールの「高度な設定」から「Bot として設定」のチェックを入れること
* タイムラインへの投稿は、原則として **1日に100ート以下** とすること
- ユーザーからのメンションへの返信は対象外です
* **Botアカウントと交流する意思がないユーザーの通知欄を汚さないこと**
- Botアカウントが他のユーザーをフォローしてよいのは、以下の場合に限ります:
- ユーザーが先にBotアカウントをフォローした場合
- Botアカウントが他のユーザーをメンションしたり、投稿にリアクションや返信をしてよいのは、以下の場合のいずれかに限ります:
- ユーザーがBotアカウントをフォローしている場合
- ユーザーがBotアカウントをメンションした場合
- ユーザーがBotアカウントの投稿に返信した場合
- ユーザーが `#nobot` などの形でBotからのオプトアウトを表明している場合は、**いずれの行為も禁止です**
再三の注意・警告を経ても、このルールに従って頂けない/連絡がつかない場合、当該Botアカウントのサイレンスまたはログイン停止処理を行うことがあります。
--->
### もしもの際は
管理者の連絡先として利用可能な経路の一覧です。信頼できる経路を選択してください。また、可能な限り連絡者とアカウントが同一人物であることを確認できる手段を推奨しています。
- Keybase <a href="https://keybase.io/cannorin" target="_blank">@cannorin</a>
- おそらく最もセキュア。
- 当サーバーの <a href="https://misskey.cannorin.net/@admin" target="_blank">@admin</a> または <a href="https://misskey.cannorin.net/@cannorin" target="_blank">@cannorin</a>
- 公開範囲をダイレクトにしてください。
- Discord <a href="https://discord.com/users/497190979216867329" target="_blank">@cannorin</a>
- フレンドを送ってからDMを送信してください。
- X (Twitter) <a href="https://x.com/cannorin3" target="_blank">@cannorin3</a>
- 通知を見落としがちなのであんまり推奨しないです。

View File

@@ -0,0 +1,21 @@
* {
--foreground: 152 13 26;
--background: 254 248 249;
--background-darken: 252 235 238;
--muted-foreground: 219 96 114;
--border: 152 13 26;
--input: 152 13 26;
--ring: 152 13 26;
--primary: 219 96 114;
--primary-darken: 210 54 77;
--primary-lighten: 228 138 151;
--primary-foreground: 254 248 249;
--secondary: 219 119 96;
--secondary-foreground: 254 248 249;
color-scheme: only light;
}

File diff suppressed because it is too large Load Diff