diff --git a/index.js b/index.js
index a7a92cb..ec2bfde 100644
--- a/index.js
+++ b/index.js
@@ -178,7 +178,7 @@ export default class ActivityPubEndpoint {
router.get("/admin/followers", followersController(mp));
router.get("/admin/following", followingController(mp));
router.get("/admin/activities", activitiesController(mp));
- router.get("/admin/migrate", migrateGetController(mp));
+ router.get("/admin/migrate", migrateGetController(mp, this.options));
router.post("/admin/migrate", migratePostController(mp, this.options));
return router;
diff --git a/lib/controllers/migrate.js b/lib/controllers/migrate.js
index f3c97c8..f4fb2c9 100644
--- a/lib/controllers/migrate.js
+++ b/lib/controllers/migrate.js
@@ -12,12 +12,13 @@ import {
bulkImportFollowers,
} from "../migration.js";
-export function migrateGetController(mountPath) {
+export function migrateGetController(mountPath, pluginOptions) {
return async (request, response, next) => {
try {
response.render("activitypub-migrate", {
title: response.locals.__("activitypub.migrate.title"),
mountPath,
+ currentAlias: pluginOptions.alsoKnownAs || "",
result: null,
});
} catch (error) {
@@ -94,6 +95,7 @@ export function migratePostController(mountPath, pluginOptions) {
response.render("activitypub-migrate", {
title: response.locals.__("activitypub.migrate.title"),
mountPath,
+ currentAlias: pluginOptions.alsoKnownAs || "",
result,
});
} catch (error) {
diff --git a/locales/en.json b/locales/en.json
index 4f25669..fdd3396 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -21,23 +21,28 @@
"directionOutbound": "Sent",
"migrate": {
"title": "Mastodon migration",
- "step1Title": "Step 1 — Configure actor alias",
- "step1Desc": "Link your old Mastodon account to this actor so the fediverse knows they are the same person.",
- "aliasLabel": "Your old Mastodon account URL",
- "aliasHint": "e.g. https://mstdn.social/users/rmdes — sets alsoKnownAs on your actor",
+ "intro": "This guide walks you through moving your Mastodon identity to your IndieWeb site. Complete each step in order — your existing followers will be notified and can re-follow you automatically.",
+ "step1Title": "Step 1 — Link your old account",
+ "step1Desc": "Tell the fediverse that your old Mastodon account and this site belong to the same person. This sets the alsoKnownAs property on your ActivityPub actor, which Mastodon checks before allowing a Move.",
+ "aliasLabel": "Old Mastodon account URL",
+ "aliasHint": "The full URL of your Mastodon profile, e.g. https://mstdn.social/users/rmdes",
"aliasSave": "Save alias",
- "step2Title": "Step 2 — Import followers/following",
- "step2Desc": "Upload your Mastodon data export CSV to import your social graph.",
- "importLabel": "Import followers and following",
- "fileLabel": "Mastodon export CSV",
- "fileHint": "Upload following_accounts.csv from your Mastodon data export",
+ "aliasCurrent": "Current alias",
+ "aliasNone": "No alias configured yet.",
+ "step2Title": "Step 2 — Import your social graph",
+ "step2Desc": "Upload the CSV files from your Mastodon data export to bring over your connections. Go to your Mastodon instance → Preferences → Import and export → Data export to download them.",
+ "importLegend": "What to import",
+ "fileLabel": "CSV file",
+ "fileHint": "Select a CSV file from your Mastodon data export (e.g. following_accounts.csv or followers.csv)",
"importButton": "Import",
- "importFollowing": "Import following list",
- "importFollowers": "Import followers list (pending until they re-follow after Move)",
- "step3Title": "Step 3 — Trigger Move on Mastodon",
- "step3Desc": "Go to your Mastodon instance → Preferences → Account → Move to a different account. Enter your new handle and confirm. After the Move, followers will automatically re-follow you here.",
+ "importFollowing": "Following list",
+ "importFollowingHint": "Accounts you follow — they will appear in your Following list immediately",
+ "importFollowers": "Followers list",
+ "importFollowersHint": "Your current followers — they will be recorded as pending until they re-follow you after the Move in step 3",
+ "step3Title": "Step 3 — Move your account",
+ "step3Desc": "Once you have saved your alias and imported your data, go to your Mastodon instance → Preferences → Account → Move to a different account. Enter your new fediverse handle and confirm. Mastodon will notify all your followers, and those whose servers support it will automatically re-follow you here. This step is irreversible — your old account will become a redirect.",
"success": "Imported %d following, %d followers (%d failed).",
- "aliasSuccess": "Actor alias updated."
+ "aliasSuccess": "Alias saved — your actor document now includes this account as alsoKnownAs."
}
}
}
diff --git a/package.json b/package.json
index 9ee52a5..819698e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@rmdes/indiekit-endpoint-activitypub",
- "version": "0.1.5",
+ "version": "0.1.6",
"description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.",
"keywords": [
"indiekit",
diff --git a/views/activitypub-migrate.njk b/views/activitypub-migrate.njk
index 2cc7c8e..ce8f59a 100644
--- a/views/activitypub-migrate.njk
+++ b/views/activitypub-migrate.njk
@@ -5,9 +5,9 @@
{% from "button/macro.njk" import button with context %}
{% from "checkboxes/macro.njk" import checkboxes with context %}
{% from "file-input/macro.njk" import fileInput with context %}
-{% from "details/macro.njk" import details with context %}
{% from "notification-banner/macro.njk" import notificationBanner with context %}
{% from "prose/macro.njk" import prose with context %}
+{% from "badge/macro.njk" import badge with context %}
{% block content %}
{{ heading({ text: title, level: 1, parent: { text: __("activitypub.title"), href: mountPath } }) }}
@@ -16,16 +16,28 @@
{{ notificationBanner({ type: result.type, text: result.text }) }}
{% endif %}
+ {{ prose({ text: __("activitypub.migrate.intro") }) }}
+
{# Step 1 — Actor alias #}
{{ heading({ text: __("activitypub.migrate.step1Title"), level: 2 }) }}
{{ prose({ text: __("activitypub.migrate.step1Desc") }) }}
+ {% if currentAlias %}
+
+ {{ __("activitypub.migrate.aliasCurrent") }}: + {{ currentAlias }} +
+ {% else %} +{{ __("activitypub.migrate.aliasNone") }}
+ {% endif %} +