···237237 }
238238 }
239239240240+ /**
241241+ * Sign and submits the PLC operation to officially migrate the account
242242+ * @param {string} token - the PLC token sent in the email. If you're just wanting to run this rerun migrate with all the flags set as false except for migratePlcRecord
243243+ * @returns {Promise<void>}
244244+ */
240245 async signPlcOperation(token) {
241246 const getDidCredentials =
242247 await this.newAgent.com.atproto.identity.getRecommendedDidCredentials();
···262267 await this.newAgent.com.atproto.server.activateAccount();
263268 await this.oldAgent.com.atproto.server.deactivateAccount({});
264269 }
270270+271271+ // Quick and dirty copy and paste of the above to get a fix out to help people without breaking or introducing any bugs to the migration service...hopefully
272272+ async deactivateOldAccount(oldHandle, oldPassword, statusUpdateHandler = null, twoFactorCode = null) {
273273+ //Copying the handle from bsky website adds some random unicodes on
274274+ oldHandle = oldHandle.replace('@', '').trim().replace(/[\u202A\u202C\u200E\u200F\u2066-\u2069]/g, '');
275275+ let usersDid;
276276+ //If it's a bsky handle just go with the entryway and let it sort everything
277277+ if (oldHandle.endsWith('.bsky.social')) {
278278+ const publicAgent = new AtpAgent({service: 'https://public.api.bsky.app'});
279279+ const resolveIdentityFromEntryway = await publicAgent.com.atproto.identity.resolveHandle({handle: oldHandle});
280280+ usersDid = resolveIdentityFromEntryway.data.did;
281281+ } else {
282282+ //Resolves the did and finds the did document for the old PDS
283283+ safeStatusUpdate(statusUpdateHandler, 'Resolving did from handle');
284284+ usersDid = await handleResolver.resolve(oldHandle);
285285+ }
286286+287287+ const didDoc = await docResolver.resolve(usersDid);
288288+ let currentPds;
289289+ try {
290290+ currentPds = didDoc.service.filter(s => s.type === 'AtprotoPersonalDataServer')[0].serviceEndpoint;
291291+ } catch (error) {
292292+ console.error(error);
293293+ throw new Error('Could not find a PDS in the DID document.');
294294+ }
295295+296296+ const plcLogRequest = await fetch(`https://plc.directory/${usersDid}/log`);
297297+ const plcLog = await plcLogRequest.json();
298298+ let pdsBeforeCurrent = '';
299299+ for (const log of plcLog) {
300300+ try {
301301+ const pds = log.services.atproto_pds.endpoint;
302302+ console.log(pds);
303303+ if (pds.toLowerCase() === currentPds.toLowerCase()) {
304304+ console.log('Found the PDS before the current one');
305305+ break;
306306+ }
307307+ pdsBeforeCurrent = pds;
308308+ } catch (e) {
309309+ console.log(e);
310310+ }
311311+ }
312312+ if (pdsBeforeCurrent === '') {
313313+ throw new Error('Could not find the PDS before the current one');
314314+ }
315315+316316+ let oldAgent = new AtpAgent({service: pdsBeforeCurrent});
317317+ safeStatusUpdate(statusUpdateHandler, `Logging you in to the old PDS: ${pdsBeforeCurrent}`);
318318+ //Login to the old PDS
319319+ if (twoFactorCode === null) {
320320+ await oldAgent.login({identifier: oldHandle, password: oldPassword});
321321+ } else {
322322+ await oldAgent.login({identifier: oldHandle, password: oldPassword, authFactorToken: twoFactorCode});
323323+ }
324324+ safeStatusUpdate(statusUpdateHandler, 'Checking this isn\'t your current PDS');
325325+ if (pdsBeforeCurrent === currentPds) {
326326+ throw new Error('This is your current PDS. Login to your old account username and password');
327327+ }
328328+329329+ let currentAccountStatus = await oldAgent.com.atproto.server.checkAccountStatus();
330330+ if (!currentAccountStatus.data.activated) {
331331+ safeStatusUpdate(statusUpdateHandler, 'All good. Your old account is not activated.');
332332+ }
333333+ safeStatusUpdate(statusUpdateHandler, 'Deactivating your OLD account');
334334+ await oldAgent.com.atproto.server.deactivateAccount({});
335335+ safeStatusUpdate(statusUpdateHandler, 'Successfully deactivated your OLD account');
336336+ }
265337}
266338267267-export {Migrator};339339+export {Migrator};