外部サービス認証情報の配信 (#3975)
* Update person.ts * Update person.ts * Update person.ts * Update person.ts * Create original model * Make type formal * Update person.ts * Follow @mei23's review refs: https://github.com/syuilo/misskey/pull/3975#pullrequestreview-195770172
This commit is contained in:
parent
4632eecb76
commit
e2f7e82cac
5
src/remote/activitypub/models/identifier.ts
Normal file
5
src/remote/activitypub/models/identifier.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
export type IIdentifier = {
|
||||
type: string;
|
||||
name: string;
|
||||
value: string;
|
||||
};
|
|
@ -19,6 +19,7 @@ import getDriveFileUrl from '../../../misc/get-drive-file-url';
|
|||
import { IEmoji } from '../../../models/emoji';
|
||||
import { ITag } from './tag';
|
||||
import Following from '../../../models/following';
|
||||
import { IIdentifier } from './identifier';
|
||||
|
||||
const log = debug('misskey:activitypub');
|
||||
|
||||
|
@ -137,9 +138,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<IU
|
|||
|
||||
const host = toUnicode(new URL(object.id).hostname.toLowerCase());
|
||||
|
||||
const fields = await extractFields(person.attachment).catch(e => {
|
||||
console.log(`cat not extract fields: ${e}`);
|
||||
});
|
||||
const { fields, services } = analyzeAttachments(person.attachment);
|
||||
|
||||
const isBot = object.type == 'Service';
|
||||
|
||||
|
@ -171,7 +170,8 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<IU
|
|||
uri: person.id,
|
||||
url: person.url,
|
||||
fields,
|
||||
isBot: isBot,
|
||||
...services,
|
||||
isBot,
|
||||
isCat: (person as any).isCat === true
|
||||
}) as IRemoteUser;
|
||||
} catch (e) {
|
||||
|
@ -332,9 +332,7 @@ export async function updatePerson(uri: string, resolver?: Resolver, hint?: obje
|
|||
|
||||
const emojiNames = emojis.map(emoji => emoji.name);
|
||||
|
||||
const fields = await extractFields(person.attachment).catch(e => {
|
||||
console.log(`cat not extract fields: ${e}`);
|
||||
});
|
||||
const { fields, services } = analyzeAttachments(person.attachment);
|
||||
|
||||
const updates = {
|
||||
lastFetchedAt: new Date(),
|
||||
|
@ -350,6 +348,7 @@ export async function updatePerson(uri: string, resolver?: Resolver, hint?: obje
|
|||
url: person.url,
|
||||
endpoints: person.endpoints,
|
||||
fields,
|
||||
...services,
|
||||
isBot: object.type == 'Service',
|
||||
isCat: (person as any).isCat === true,
|
||||
isLocked: person.manuallyApprovesFollowers,
|
||||
|
@ -413,16 +412,61 @@ export async function resolvePerson(uri: string, verifier?: string, resolver?: R
|
|||
return await createPerson(uri, resolver);
|
||||
}
|
||||
|
||||
export async function extractFields(attachments: ITag[]) {
|
||||
if (!attachments) return [];
|
||||
const isPropertyValue = (x: {
|
||||
type: string,
|
||||
name?: string,
|
||||
value?: string
|
||||
}) =>
|
||||
x &&
|
||||
x.type === 'PropertyValue' &&
|
||||
typeof x.name === 'string' &&
|
||||
typeof x.value === 'string';
|
||||
|
||||
return attachments.filter(a => a.type === 'PropertyValue' && a.name && a.value)
|
||||
.map(a => {
|
||||
return {
|
||||
name: a.name,
|
||||
value: htmlToMFM(a.value)
|
||||
};
|
||||
});
|
||||
const services: {
|
||||
[x: string]: (id: string, username: string) => any
|
||||
} = {
|
||||
'misskey:authentication:twitter': (userId, screenName) => ({ userId, screenName }),
|
||||
'misskey:authentication:github': (id, login) => ({ id, login }),
|
||||
'misskey:authentication:discord': (id, name) => $discord(id, name)
|
||||
};
|
||||
|
||||
const $discord = (id: string, name: string) => {
|
||||
if (typeof name !== 'string')
|
||||
name = 'unknown#0000';
|
||||
const [username, discriminator] = name.split('#');
|
||||
return { id, username, discriminator };
|
||||
};
|
||||
|
||||
function addService(target: { [x: string]: any }, source: IIdentifier) {
|
||||
const service = services[source.name];
|
||||
|
||||
if (typeof source.value !== 'string')
|
||||
source.value = 'unknown';
|
||||
|
||||
const [id, username] = source.value.split('@');
|
||||
|
||||
if (service)
|
||||
target[source.name.split(':')[2]] = service(id, username);
|
||||
}
|
||||
|
||||
export function analyzeAttachments(attachments: ITag[]) {
|
||||
const fields: {
|
||||
name: string,
|
||||
value: string
|
||||
}[] = [];
|
||||
const services: { [x: string]: any } = {};
|
||||
|
||||
if (Array.isArray(attachments))
|
||||
for (const attachment of attachments.filter(isPropertyValue))
|
||||
if (isPropertyValue(attachment.identifier))
|
||||
addService(services, attachment.identifier);
|
||||
else
|
||||
fields.push({
|
||||
name: attachment.name,
|
||||
value: htmlToMFM(attachment.value)
|
||||
});
|
||||
|
||||
return { fields, services };
|
||||
}
|
||||
|
||||
export async function updateFeatured(userId: mongo.ObjectID) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { IIcon } from './icon';
|
||||
import { IIdentifier } from './identifier';
|
||||
|
||||
/***
|
||||
* tag (ActivityPub)
|
||||
|
@ -10,4 +11,5 @@ export type ITag = {
|
|||
value?: string;
|
||||
updated?: Date;
|
||||
icon?: IIcon;
|
||||
identifier?: IIdentifier;
|
||||
};
|
||||
|
|
|
@ -7,6 +7,7 @@ import parse from '../../../mfm/parse';
|
|||
import DriveFile from '../../../models/drive-file';
|
||||
import { getEmojis } from './note';
|
||||
import renderEmoji from './emoji';
|
||||
import { IIdentifier } from '../models/identifier';
|
||||
|
||||
export default async (user: ILocalUser) => {
|
||||
const id = `${config.url}/users/${user._id}`;
|
||||
|
@ -20,14 +21,20 @@ export default async (user: ILocalUser) => {
|
|||
type: string,
|
||||
name: string,
|
||||
value: string,
|
||||
verified_at?: string
|
||||
verified_at?: string,
|
||||
identifier?: IIdentifier
|
||||
}[] = [];
|
||||
|
||||
if (user.twitter) {
|
||||
attachment.push({
|
||||
type: 'PropertyValue',
|
||||
name: 'Twitter',
|
||||
value: `<a href="https://twitter.com/intent/user?user_id=${user.twitter.userId}" rel="me nofollow noopener" target="_blank"><span>@${user.twitter.screenName}</span></a>`
|
||||
value: `<a href="https://twitter.com/intent/user?user_id=${user.twitter.userId}" rel="me nofollow noopener" target="_blank"><span>@${user.twitter.screenName}</span></a>`,
|
||||
identifier: {
|
||||
type: 'PropertyValue',
|
||||
name: 'misskey:authentication:twitter',
|
||||
value: `${user.twitter.userId}@${user.twitter.screenName}`
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -35,7 +42,12 @@ export default async (user: ILocalUser) => {
|
|||
attachment.push({
|
||||
type: 'PropertyValue',
|
||||
name: 'GitHub',
|
||||
value: `<a href="https://github.com/${user.github.login}" rel="me nofollow noopener" target="_blank"><span>@${user.github.login}</span></a>`
|
||||
value: `<a href="https://github.com/${user.github.login}" rel="me nofollow noopener" target="_blank"><span>@${user.github.login}</span></a>`,
|
||||
identifier: {
|
||||
type: 'PropertyValue',
|
||||
name: 'misskey:authentication:github',
|
||||
value: `${user.github.id}@${user.github.login}`
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -43,7 +55,12 @@ export default async (user: ILocalUser) => {
|
|||
attachment.push({
|
||||
type: 'PropertyValue',
|
||||
name: 'Discord',
|
||||
value: `<a href="https://discordapp.com/users/${user.discord.id}" rel="me nofollow noopener" target="_blank"><span>${user.discord.username}#${user.discord.discriminator}</span></a>`
|
||||
value: `<a href="https://discordapp.com/users/${user.discord.id}" rel="me nofollow noopener" target="_blank"><span>${user.discord.username}#${user.discord.discriminator}</span></a>`,
|
||||
identifier: {
|
||||
type: 'PropertyValue',
|
||||
name: 'misskey:authentication:discord',
|
||||
value: `${user.discord.id}@${user.discord.username}#${user.discord.discriminator}`
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue