テーブル分割
This commit is contained in:
parent
9603f3fa4f
commit
626cfb61ac
|
@ -36,10 +36,10 @@ import { Emoji } from '../models/entities/emoji';
|
||||||
import { ReversiGame } from '../models/entities/games/reversi/game';
|
import { ReversiGame } from '../models/entities/games/reversi/game';
|
||||||
import { ReversiMatching } from '../models/entities/games/reversi/matching';
|
import { ReversiMatching } from '../models/entities/games/reversi/matching';
|
||||||
import { UserNotePining } from '../models/entities/user-note-pinings';
|
import { UserNotePining } from '../models/entities/user-note-pinings';
|
||||||
import { UserServiceLinking } from '../models/entities/user-service-linking';
|
|
||||||
import { Poll } from '../models/entities/poll';
|
import { Poll } from '../models/entities/poll';
|
||||||
import { UserKeypair } from '../models/entities/user-keypair';
|
import { UserKeypair } from '../models/entities/user-keypair';
|
||||||
import { UserPublickey } from '../models/entities/user-publickey';
|
import { UserPublickey } from '../models/entities/user-publickey';
|
||||||
|
import { UserProfile } from '../models/entities/user-profile';
|
||||||
|
|
||||||
const sqlLogger = dbLogger.createSubLogger('sql', 'white', false);
|
const sqlLogger = dbLogger.createSubLogger('sql', 'white', false);
|
||||||
|
|
||||||
|
@ -101,12 +101,12 @@ export function initDb(justBorrow = false, sync = false, log = false) {
|
||||||
AuthSession,
|
AuthSession,
|
||||||
AccessToken,
|
AccessToken,
|
||||||
User,
|
User,
|
||||||
|
UserProfile,
|
||||||
UserKeypair,
|
UserKeypair,
|
||||||
UserPublickey,
|
UserPublickey,
|
||||||
UserList,
|
UserList,
|
||||||
UserListJoining,
|
UserListJoining,
|
||||||
UserNotePining,
|
UserNotePining,
|
||||||
UserServiceLinking,
|
|
||||||
Following,
|
Following,
|
||||||
FollowRequest,
|
FollowRequest,
|
||||||
Muting,
|
Muting,
|
||||||
|
|
|
@ -26,6 +26,7 @@ import { UserKeypair } from './models/entities/user-keypair';
|
||||||
import { extractPublic } from './crypto_key';
|
import { extractPublic } from './crypto_key';
|
||||||
import { Emoji } from './models/entities/emoji';
|
import { Emoji } from './models/entities/emoji';
|
||||||
import { toPuny } from './misc/convert-host';
|
import { toPuny } from './misc/convert-host';
|
||||||
|
import { UserProfile } from './models/entities/user-profile';
|
||||||
|
|
||||||
const u = (config as any).mongodb.user ? encodeURIComponent((config as any).mongodb.user) : null;
|
const u = (config as any).mongodb.user ? encodeURIComponent((config as any).mongodb.user) : null;
|
||||||
const p = (config as any).mongodb.pass ? encodeURIComponent((config as any).mongodb.pass) : null;
|
const p = (config as any).mongodb.pass ? encodeURIComponent((config as any).mongodb.pass) : null;
|
||||||
|
@ -70,6 +71,7 @@ const getDriveFileBucket = async (): Promise<mongo.GridFSBucket> => {
|
||||||
async function main() {
|
async function main() {
|
||||||
await initDb();
|
await initDb();
|
||||||
const Users = getRepository(User);
|
const Users = getRepository(User);
|
||||||
|
const UserProfiles = getRepository(UserProfile);
|
||||||
const DriveFiles = getRepository(DriveFile);
|
const DriveFiles = getRepository(DriveFile);
|
||||||
const DriveFolders = getRepository(DriveFolder);
|
const DriveFolders = getRepository(DriveFolder);
|
||||||
const Notes = getRepository(Note);
|
const Notes = getRepository(Note);
|
||||||
|
@ -90,17 +92,11 @@ async function main() {
|
||||||
usernameLower: user.username.toLowerCase(),
|
usernameLower: user.username.toLowerCase(),
|
||||||
host: toPuny(user.host),
|
host: toPuny(user.host),
|
||||||
token: generateUserToken(),
|
token: generateUserToken(),
|
||||||
password: user.password,
|
|
||||||
isAdmin: user.isAdmin,
|
isAdmin: user.isAdmin,
|
||||||
autoAcceptFollowed: true,
|
|
||||||
autoWatch: false,
|
|
||||||
name: user.name,
|
name: user.name,
|
||||||
location: user.profile ? user.profile.location : null,
|
|
||||||
birthday: user.profile ? user.profile.birthday : null,
|
|
||||||
followersCount: user.followersCount,
|
followersCount: user.followersCount,
|
||||||
followingCount: user.followingCount,
|
followingCount: user.followingCount,
|
||||||
notesCount: user.notesCount,
|
notesCount: user.notesCount,
|
||||||
description: user.description,
|
|
||||||
isBot: user.isBot,
|
isBot: user.isBot,
|
||||||
isCat: user.isCat,
|
isCat: user.isCat,
|
||||||
isVerified: user.isVerified,
|
isVerified: user.isVerified,
|
||||||
|
@ -108,9 +104,18 @@ async function main() {
|
||||||
sharedInbox: user.sharedInbox,
|
sharedInbox: user.sharedInbox,
|
||||||
uri: user.uri,
|
uri: user.uri,
|
||||||
});
|
});
|
||||||
|
await UserProfiles.save({
|
||||||
|
userId: user._id.toHexString(),
|
||||||
|
description: user.description,
|
||||||
|
userHost: toPuny(user.host),
|
||||||
|
autoAcceptFollowed: true,
|
||||||
|
autoWatch: false,
|
||||||
|
password: user.password,
|
||||||
|
location: user.profile ? user.profile.location : null,
|
||||||
|
birthday: user.profile ? user.profile.birthday : null,
|
||||||
|
});
|
||||||
if (user.publicKey) {
|
if (user.publicKey) {
|
||||||
await UserPublickeys.save({
|
await UserPublickeys.save({
|
||||||
id: genId(),
|
|
||||||
userId: user._id.toHexString(),
|
userId: user._id.toHexString(),
|
||||||
keyId: user.publicKey.id,
|
keyId: user.publicKey.id,
|
||||||
keyPem: user.publicKey.publicKeyPem
|
keyPem: user.publicKey.publicKeyPem
|
||||||
|
@ -118,7 +123,6 @@ async function main() {
|
||||||
}
|
}
|
||||||
if (user.keypair) {
|
if (user.keypair) {
|
||||||
await UserKeypairs.save({
|
await UserKeypairs.save({
|
||||||
id: genId(),
|
|
||||||
userId: user._id.toHexString(),
|
userId: user._id.toHexString(),
|
||||||
publicKey: extractPublic(user.keypair),
|
publicKey: extractPublic(user.keypair),
|
||||||
privateKey: user.keypair,
|
privateKey: user.keypair,
|
||||||
|
|
|
@ -4,11 +4,8 @@ import { id } from '../id';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class UserKeypair {
|
export class UserKeypair {
|
||||||
@PrimaryColumn(id())
|
|
||||||
public id: string;
|
|
||||||
|
|
||||||
@Index({ unique: true })
|
@Index({ unique: true })
|
||||||
@Column(id())
|
@PrimaryColumn(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@OneToOne(type => User, {
|
@OneToOne(type => User, {
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
import { PrimaryColumn, Entity, Index, JoinColumn, Column, OneToOne } from 'typeorm';
|
import { Entity, Column, Index, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm';
|
||||||
import { User } from './user';
|
|
||||||
import { id } from '../id';
|
import { id } from '../id';
|
||||||
|
import { User } from './user';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class UserServiceLinking {
|
export class UserProfile {
|
||||||
@PrimaryColumn(id())
|
|
||||||
public id: string;
|
|
||||||
|
|
||||||
@Index({ unique: true })
|
@Index({ unique: true })
|
||||||
@Column(id())
|
@PrimaryColumn(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@OneToOne(type => User, {
|
@OneToOne(type => User, {
|
||||||
|
@ -17,6 +14,96 @@ export class UserServiceLinking {
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
public user: User | null;
|
public user: User | null;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 128, nullable: true,
|
||||||
|
comment: 'The location of the User.'
|
||||||
|
})
|
||||||
|
public location: string | null;
|
||||||
|
|
||||||
|
@Column('char', {
|
||||||
|
length: 10, nullable: true,
|
||||||
|
comment: 'The birthday (YYYY-MM-DD) of the User.'
|
||||||
|
})
|
||||||
|
public birthday: string | null;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 1024, nullable: true,
|
||||||
|
comment: 'The description (bio) of the User.'
|
||||||
|
})
|
||||||
|
public description: string | null;
|
||||||
|
|
||||||
|
@Column('jsonb', {
|
||||||
|
default: [],
|
||||||
|
})
|
||||||
|
public fields: {
|
||||||
|
name: string;
|
||||||
|
value: string;
|
||||||
|
}[];
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 128, nullable: true,
|
||||||
|
comment: 'The email address of the User.'
|
||||||
|
})
|
||||||
|
public email: string | null;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 128, nullable: true,
|
||||||
|
})
|
||||||
|
public emailVerifyCode: string | null;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
public emailVerified: boolean;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 128, nullable: true,
|
||||||
|
})
|
||||||
|
public twoFactorTempSecret: string | null;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 128, nullable: true,
|
||||||
|
})
|
||||||
|
public twoFactorSecret: string | null;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
public twoFactorEnabled: boolean;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 128, nullable: true,
|
||||||
|
comment: 'The password hash of the User. It will be null if the origin of the user is local.'
|
||||||
|
})
|
||||||
|
public password: string | null;
|
||||||
|
|
||||||
|
@Column('jsonb', {
|
||||||
|
default: {},
|
||||||
|
comment: 'The client-specific data of the User.'
|
||||||
|
})
|
||||||
|
public clientData: Record<string, any>;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
public autoWatch: boolean;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
public autoAcceptFollowed: boolean;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
public alwaysMarkNsfw: boolean;
|
||||||
|
|
||||||
|
@Column('boolean', {
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
public carefulBot: boolean;
|
||||||
|
|
||||||
|
//#region Linking
|
||||||
@Column('boolean', {
|
@Column('boolean', {
|
||||||
default: false,
|
default: false,
|
||||||
})
|
})
|
||||||
|
@ -96,6 +183,7 @@ export class UserServiceLinking {
|
||||||
length: 64, nullable: true, default: null,
|
length: 64, nullable: true, default: null,
|
||||||
})
|
})
|
||||||
public discordDiscriminator: string | null;
|
public discordDiscriminator: string | null;
|
||||||
|
//#endregion
|
||||||
|
|
||||||
//#region Denormalized fields
|
//#region Denormalized fields
|
||||||
@Index()
|
@Index()
|
|
@ -4,11 +4,8 @@ import { id } from '../id';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class UserPublickey {
|
export class UserPublickey {
|
||||||
@PrimaryColumn(id())
|
|
||||||
public id: string;
|
|
||||||
|
|
||||||
@Index({ unique: true })
|
@Index({ unique: true })
|
||||||
@Column(id())
|
@PrimaryColumn(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@OneToOne(type => User, {
|
@OneToOne(type => User, {
|
||||||
|
|
|
@ -45,18 +45,6 @@ export class User {
|
||||||
})
|
})
|
||||||
public name: string | null;
|
public name: string | null;
|
||||||
|
|
||||||
@Column('varchar', {
|
|
||||||
length: 128, nullable: true,
|
|
||||||
comment: 'The location of the User.'
|
|
||||||
})
|
|
||||||
public location: string | null;
|
|
||||||
|
|
||||||
@Column('char', {
|
|
||||||
length: 10, nullable: true,
|
|
||||||
comment: 'The birthday (YYYY-MM-DD) of the User.'
|
|
||||||
})
|
|
||||||
public birthday: string | null;
|
|
||||||
|
|
||||||
@Column('integer', {
|
@Column('integer', {
|
||||||
default: 0,
|
default: 0,
|
||||||
comment: 'The count of followers.'
|
comment: 'The count of followers.'
|
||||||
|
@ -101,44 +89,12 @@ export class User {
|
||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
public banner: DriveFile | null;
|
public banner: DriveFile | null;
|
||||||
|
|
||||||
@Column('varchar', {
|
|
||||||
length: 1024, nullable: true,
|
|
||||||
comment: 'The description (bio) of the User.'
|
|
||||||
})
|
|
||||||
public description: string | null;
|
|
||||||
|
|
||||||
@Index()
|
@Index()
|
||||||
@Column('varchar', {
|
@Column('varchar', {
|
||||||
length: 128, array: true, default: '{}'
|
length: 128, array: true, default: '{}'
|
||||||
})
|
})
|
||||||
public tags: string[];
|
public tags: string[];
|
||||||
|
|
||||||
@Column('varchar', {
|
|
||||||
length: 128, nullable: true,
|
|
||||||
comment: 'The email address of the User.'
|
|
||||||
})
|
|
||||||
public email: string | null;
|
|
||||||
|
|
||||||
@Column('varchar', {
|
|
||||||
length: 128, nullable: true,
|
|
||||||
})
|
|
||||||
public emailVerifyCode: string | null;
|
|
||||||
|
|
||||||
@Column('boolean', {
|
|
||||||
default: false,
|
|
||||||
})
|
|
||||||
public emailVerified: boolean;
|
|
||||||
|
|
||||||
@Column('varchar', {
|
|
||||||
length: 128, nullable: true,
|
|
||||||
})
|
|
||||||
public twoFactorTempSecret: string | null;
|
|
||||||
|
|
||||||
@Column('varchar', {
|
|
||||||
length: 128, nullable: true,
|
|
||||||
})
|
|
||||||
public twoFactorSecret: string | null;
|
|
||||||
|
|
||||||
@Column('varchar', {
|
@Column('varchar', {
|
||||||
length: 256, nullable: true,
|
length: 256, nullable: true,
|
||||||
})
|
})
|
||||||
|
@ -206,11 +162,6 @@ export class User {
|
||||||
})
|
})
|
||||||
public isVerified: boolean;
|
public isVerified: boolean;
|
||||||
|
|
||||||
@Column('boolean', {
|
|
||||||
default: false,
|
|
||||||
})
|
|
||||||
public twoFactorEnabled: boolean;
|
|
||||||
|
|
||||||
@Column('varchar', {
|
@Column('varchar', {
|
||||||
length: 128, array: true, default: '{}'
|
length: 128, array: true, default: '{}'
|
||||||
})
|
})
|
||||||
|
@ -248,44 +199,12 @@ export class User {
|
||||||
})
|
})
|
||||||
public uri: string | null;
|
public uri: string | null;
|
||||||
|
|
||||||
@Column('varchar', {
|
|
||||||
length: 128, nullable: true,
|
|
||||||
comment: 'The password hash of the User. It will be null if the origin of the user is local.'
|
|
||||||
})
|
|
||||||
public password: string | null;
|
|
||||||
|
|
||||||
@Index({ unique: true })
|
@Index({ unique: true })
|
||||||
@Column('char', {
|
@Column('char', {
|
||||||
length: 16, nullable: true, unique: true,
|
length: 16, nullable: true, unique: true,
|
||||||
comment: 'The native access token of the User. It will be null if the origin of the user is local.'
|
comment: 'The native access token of the User. It will be null if the origin of the user is local.'
|
||||||
})
|
})
|
||||||
public token: string | null;
|
public token: string | null;
|
||||||
|
|
||||||
@Column('jsonb', {
|
|
||||||
default: {},
|
|
||||||
comment: 'The client-specific data of the User.'
|
|
||||||
})
|
|
||||||
public clientData: Record<string, any>;
|
|
||||||
|
|
||||||
@Column('boolean', {
|
|
||||||
default: false,
|
|
||||||
})
|
|
||||||
public autoWatch: boolean;
|
|
||||||
|
|
||||||
@Column('boolean', {
|
|
||||||
default: false,
|
|
||||||
})
|
|
||||||
public autoAcceptFollowed: boolean;
|
|
||||||
|
|
||||||
@Column('boolean', {
|
|
||||||
default: false,
|
|
||||||
})
|
|
||||||
public alwaysMarkNsfw: boolean;
|
|
||||||
|
|
||||||
@Column('boolean', {
|
|
||||||
default: false,
|
|
||||||
})
|
|
||||||
public carefulBot: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ILocalUser extends User {
|
export interface ILocalUser extends User {
|
||||||
|
|
|
@ -25,7 +25,6 @@ import { FollowRequestRepository } from './repositories/follow-request';
|
||||||
import { MutingRepository } from './repositories/muting';
|
import { MutingRepository } from './repositories/muting';
|
||||||
import { BlockingRepository } from './repositories/blocking';
|
import { BlockingRepository } from './repositories/blocking';
|
||||||
import { NoteReactionRepository } from './repositories/note-reaction';
|
import { NoteReactionRepository } from './repositories/note-reaction';
|
||||||
import { UserServiceLinking } from './entities/user-service-linking';
|
|
||||||
import { NotificationRepository } from './repositories/notification';
|
import { NotificationRepository } from './repositories/notification';
|
||||||
import { NoteFavoriteRepository } from './repositories/note-favorite';
|
import { NoteFavoriteRepository } from './repositories/note-favorite';
|
||||||
import { ReversiMatchingRepository } from './repositories/games/reversi/matching';
|
import { ReversiMatchingRepository } from './repositories/games/reversi/matching';
|
||||||
|
@ -35,6 +34,7 @@ import { AppRepository } from './repositories/app';
|
||||||
import { FollowingRepository } from './repositories/following';
|
import { FollowingRepository } from './repositories/following';
|
||||||
import { AbuseUserReportRepository } from './repositories/abuse-user-report';
|
import { AbuseUserReportRepository } from './repositories/abuse-user-report';
|
||||||
import { AuthSessionRepository } from './repositories/auth-session';
|
import { AuthSessionRepository } from './repositories/auth-session';
|
||||||
|
import { UserProfile } from './entities/user-profile';
|
||||||
|
|
||||||
export const Apps = getCustomRepository(AppRepository);
|
export const Apps = getCustomRepository(AppRepository);
|
||||||
export const Notes = getCustomRepository(NoteRepository);
|
export const Notes = getCustomRepository(NoteRepository);
|
||||||
|
@ -45,12 +45,12 @@ export const NoteUnreads = getRepository(NoteUnread);
|
||||||
export const Polls = getRepository(Poll);
|
export const Polls = getRepository(Poll);
|
||||||
export const PollVotes = getRepository(PollVote);
|
export const PollVotes = getRepository(PollVote);
|
||||||
export const Users = getCustomRepository(UserRepository);
|
export const Users = getCustomRepository(UserRepository);
|
||||||
|
export const UserProfiles = getRepository(UserProfile);
|
||||||
export const UserKeypairs = getRepository(UserKeypair);
|
export const UserKeypairs = getRepository(UserKeypair);
|
||||||
export const UserPublickeys = getRepository(UserPublickey);
|
export const UserPublickeys = getRepository(UserPublickey);
|
||||||
export const UserLists = getCustomRepository(UserListRepository);
|
export const UserLists = getCustomRepository(UserListRepository);
|
||||||
export const UserListJoinings = getRepository(UserListJoining);
|
export const UserListJoinings = getRepository(UserListJoining);
|
||||||
export const UserNotePinings = getRepository(UserNotePining);
|
export const UserNotePinings = getRepository(UserNotePining);
|
||||||
export const UserServiceLinkings = getRepository(UserServiceLinking);
|
|
||||||
export const Followings = getCustomRepository(FollowingRepository);
|
export const Followings = getCustomRepository(FollowingRepository);
|
||||||
export const FollowRequests = getCustomRepository(FollowRequestRepository);
|
export const FollowRequests = getCustomRepository(FollowRequestRepository);
|
||||||
export const Instances = getRepository(Instance);
|
export const Instances = getRepository(Instance);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { EntityRepository, Repository, In } from 'typeorm';
|
import { EntityRepository, Repository, In } from 'typeorm';
|
||||||
import { User, ILocalUser, IRemoteUser } from '../entities/user';
|
import { User, ILocalUser, IRemoteUser } from '../entities/user';
|
||||||
import { Emojis, Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings } from '..';
|
import { Emojis, Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles } from '..';
|
||||||
import rap from '@prezzemolo/rap';
|
import rap from '@prezzemolo/rap';
|
||||||
|
|
||||||
@EntityRepository(User)
|
@EntityRepository(User)
|
||||||
|
@ -80,6 +80,7 @@ export class UserRepository extends Repository<User> {
|
||||||
|
|
||||||
const relation = meId && (meId !== user.id) && opts.detail ? await this.getRelation(meId, user.id) : null;
|
const relation = meId && (meId !== user.id) && opts.detail ? await this.getRelation(meId, user.id) : null;
|
||||||
const pins = opts.detail ? await UserNotePinings.find({ userId: user.id }) : [];
|
const pins = opts.detail ? await UserNotePinings.find({ userId: user.id }) : [];
|
||||||
|
const profile = opts.detail ? await UserProfiles.findOne({ userId: user.id }) : null;
|
||||||
|
|
||||||
return await rap({
|
return await rap({
|
||||||
id: user.id,
|
id: user.id,
|
||||||
|
@ -116,9 +117,9 @@ export class UserRepository extends Repository<User> {
|
||||||
} : {}),
|
} : {}),
|
||||||
|
|
||||||
...(opts.detail ? {
|
...(opts.detail ? {
|
||||||
description: user.description,
|
description: profile.description,
|
||||||
location: user.location,
|
location: profile.location,
|
||||||
birthday: user.birthday,
|
birthday: profile.birthday,
|
||||||
followersCount: user.followersCount,
|
followersCount: user.followersCount,
|
||||||
followingCount: user.followingCount,
|
followingCount: user.followingCount,
|
||||||
notesCount: user.notesCount,
|
notesCount: user.notesCount,
|
||||||
|
@ -131,9 +132,9 @@ export class UserRepository extends Repository<User> {
|
||||||
...(opts.detail && meId === user.id ? {
|
...(opts.detail && meId === user.id ? {
|
||||||
avatarId: user.avatarId,
|
avatarId: user.avatarId,
|
||||||
bannerId: user.bannerId,
|
bannerId: user.bannerId,
|
||||||
autoWatch: user.autoWatch,
|
autoWatch: profile.autoWatch,
|
||||||
alwaysMarkNsfw: user.alwaysMarkNsfw,
|
alwaysMarkNsfw: profile.alwaysMarkNsfw,
|
||||||
carefulBot: user.carefulBot,
|
carefulBot: profile.carefulBot,
|
||||||
hasUnreadMessagingMessage: MessagingMessages.count({
|
hasUnreadMessagingMessage: MessagingMessages.count({
|
||||||
where: {
|
where: {
|
||||||
recipientId: user.id,
|
recipientId: user.id,
|
||||||
|
|
|
@ -14,16 +14,16 @@ import { IIdentifier } from './identifier';
|
||||||
import { apLogger } from '../logger';
|
import { apLogger } from '../logger';
|
||||||
import { Note } from '../../../models/entities/note';
|
import { Note } from '../../../models/entities/note';
|
||||||
import { updateHashtag } from '../../../services/update-hashtag';
|
import { updateHashtag } from '../../../services/update-hashtag';
|
||||||
import { Users, UserNotePinings, Instances, DriveFiles, Followings, UserServiceLinkings, UserPublickeys } from '../../../models';
|
import { Users, UserNotePinings, Instances, DriveFiles, Followings, UserProfiles, UserPublickeys } from '../../../models';
|
||||||
import { User, IRemoteUser } from '../../../models/entities/user';
|
import { User, IRemoteUser } from '../../../models/entities/user';
|
||||||
import { Emoji } from '../../../models/entities/emoji';
|
import { Emoji } from '../../../models/entities/emoji';
|
||||||
import { UserNotePining } from '../../../models/entities/user-note-pinings';
|
import { UserNotePining } from '../../../models/entities/user-note-pinings';
|
||||||
import { genId } from '../../../misc/gen-id';
|
import { genId } from '../../../misc/gen-id';
|
||||||
import { UserServiceLinking } from '../../../models/entities/user-service-linking';
|
|
||||||
import { instanceChart, usersChart } from '../../../services/chart';
|
import { instanceChart, usersChart } from '../../../services/chart';
|
||||||
import { UserPublickey } from '../../../models/entities/user-publickey';
|
import { UserPublickey } from '../../../models/entities/user-publickey';
|
||||||
import { isDuplicateKeyValueError } from '../../../misc/is-duplicate-key-value-error';
|
import { isDuplicateKeyValueError } from '../../../misc/is-duplicate-key-value-error';
|
||||||
import { toPuny } from '../../../misc/convert-host';
|
import { toPuny } from '../../../misc/convert-host';
|
||||||
|
import { UserProfile } from '../../../models/entities/user-profile';
|
||||||
const logger = apLogger;
|
const logger = apLogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,7 +126,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
|
||||||
|
|
||||||
const host = toPuny(new URL(object.id).hostname);
|
const host = toPuny(new URL(object.id).hostname);
|
||||||
|
|
||||||
const { fields, services } = analyzeAttachments(person.attachment);
|
const { fields } = analyzeAttachments(person.attachment);
|
||||||
|
|
||||||
const tags = extractHashtags(person.tag).map(tag => tag.toLowerCase());
|
const tags = extractHashtags(person.tag).map(tag => tag.toLowerCase());
|
||||||
|
|
||||||
|
@ -141,7 +141,6 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
|
||||||
bannerId: null,
|
bannerId: null,
|
||||||
createdAt: Date.parse(person.published) || new Date(),
|
createdAt: Date.parse(person.published) || new Date(),
|
||||||
lastFetchedAt: new Date(),
|
lastFetchedAt: new Date(),
|
||||||
description: fromHtml(person.summary),
|
|
||||||
name: person.name,
|
name: person.name,
|
||||||
isLocked: person.manuallyApprovesFollowers,
|
isLocked: person.manuallyApprovesFollowers,
|
||||||
username: person.preferredUsername,
|
username: person.preferredUsername,
|
||||||
|
@ -153,8 +152,6 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
|
||||||
endpoints: person.endpoints,
|
endpoints: person.endpoints,
|
||||||
uri: person.id,
|
uri: person.id,
|
||||||
url: person.url,
|
url: person.url,
|
||||||
fields,
|
|
||||||
...services,
|
|
||||||
tags,
|
tags,
|
||||||
isBot,
|
isBot,
|
||||||
isCat: (person as any).isCat === true
|
isCat: (person as any).isCat === true
|
||||||
|
@ -169,18 +166,18 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await UserProfiles.save({
|
||||||
|
userId: user.id,
|
||||||
|
description: fromHtml(person.summary),
|
||||||
|
fields,
|
||||||
|
} as Partial<UserProfile>);
|
||||||
|
|
||||||
await UserPublickeys.save({
|
await UserPublickeys.save({
|
||||||
id: genId(),
|
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
keyId: person.publicKey.id,
|
keyId: person.publicKey.id,
|
||||||
keyPem: person.publicKey.publicKeyPem
|
keyPem: person.publicKey.publicKeyPem
|
||||||
} as UserPublickey);
|
} as UserPublickey);
|
||||||
|
|
||||||
await UserServiceLinkings.save({
|
|
||||||
id: genId(),
|
|
||||||
userId: user.id
|
|
||||||
} as UserServiceLinking);
|
|
||||||
|
|
||||||
// Register host
|
// Register host
|
||||||
registerOrFetchInstanceDoc(host).then(i => {
|
registerOrFetchInstanceDoc(host).then(i => {
|
||||||
Instances.increment({ id: i.id }, 'usersCount', 1);
|
Instances.increment({ id: i.id }, 'usersCount', 1);
|
||||||
|
@ -347,7 +344,7 @@ export async function updatePerson(uri: string, resolver?: Resolver, hint?: obje
|
||||||
keyPem: person.publicKey.publicKeyPem
|
keyPem: person.publicKey.publicKeyPem
|
||||||
});
|
});
|
||||||
|
|
||||||
await UserServiceLinkings.update({ userId: exist.id }, {
|
await UserProfiles.update({ userId: exist.id }, {
|
||||||
twitterUserId: services.twitter.userId,
|
twitterUserId: services.twitter.userId,
|
||||||
twitterScreenName: services.twitter.screenName,
|
twitterScreenName: services.twitter.screenName,
|
||||||
githubId: services.github.id,
|
githubId: services.github.id,
|
||||||
|
|
|
@ -8,15 +8,15 @@ import { getEmojis } from './note';
|
||||||
import renderEmoji from './emoji';
|
import renderEmoji from './emoji';
|
||||||
import { IIdentifier } from '../models/identifier';
|
import { IIdentifier } from '../models/identifier';
|
||||||
import renderHashtag from './hashtag';
|
import renderHashtag from './hashtag';
|
||||||
import { DriveFiles, UserServiceLinkings, UserKeypairs } from '../../../models';
|
import { DriveFiles, UserProfiles, UserKeypairs } from '../../../models';
|
||||||
|
|
||||||
export async function renderPerson(user: ILocalUser) {
|
export async function renderPerson(user: ILocalUser) {
|
||||||
const id = `${config.url}/users/${user.id}`;
|
const id = `${config.url}/users/${user.id}`;
|
||||||
|
|
||||||
const [avatar, banner, links] = await Promise.all([
|
const [avatar, banner, profile] = await Promise.all([
|
||||||
DriveFiles.findOne(user.avatarId),
|
DriveFiles.findOne(user.avatarId),
|
||||||
DriveFiles.findOne(user.bannerId),
|
DriveFiles.findOne(user.bannerId),
|
||||||
UserServiceLinkings.findOne({ userId: user.id })
|
UserProfiles.findOne({ userId: user.id })
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const attachment: {
|
const attachment: {
|
||||||
|
@ -27,41 +27,41 @@ export async function renderPerson(user: ILocalUser) {
|
||||||
identifier?: IIdentifier
|
identifier?: IIdentifier
|
||||||
}[] = [];
|
}[] = [];
|
||||||
|
|
||||||
if (links.twitter) {
|
if (profile.twitter) {
|
||||||
attachment.push({
|
attachment.push({
|
||||||
type: 'PropertyValue',
|
type: 'PropertyValue',
|
||||||
name: 'Twitter',
|
name: 'Twitter',
|
||||||
value: `<a href="https://twitter.com/intent/user?user_id=${links.twitterUserId}" rel="me nofollow noopener" target="_blank"><span>@${links.twitterScreenName}</span></a>`,
|
value: `<a href="https://twitter.com/intent/user?user_id=${profile.twitterUserId}" rel="me nofollow noopener" target="_blank"><span>@${profile.twitterScreenName}</span></a>`,
|
||||||
identifier: {
|
identifier: {
|
||||||
type: 'PropertyValue',
|
type: 'PropertyValue',
|
||||||
name: 'misskey:authentication:twitter',
|
name: 'misskey:authentication:twitter',
|
||||||
value: `${links.twitterUserId}@${links.twitterScreenName}`
|
value: `${profile.twitterUserId}@${profile.twitterScreenName}`
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (links.github) {
|
if (profile.github) {
|
||||||
attachment.push({
|
attachment.push({
|
||||||
type: 'PropertyValue',
|
type: 'PropertyValue',
|
||||||
name: 'GitHub',
|
name: 'GitHub',
|
||||||
value: `<a href="https://github.com/${links.githubLogin}" rel="me nofollow noopener" target="_blank"><span>@${links.githubLogin}</span></a>`,
|
value: `<a href="https://github.com/${profile.githubLogin}" rel="me nofollow noopener" target="_blank"><span>@${profile.githubLogin}</span></a>`,
|
||||||
identifier: {
|
identifier: {
|
||||||
type: 'PropertyValue',
|
type: 'PropertyValue',
|
||||||
name: 'misskey:authentication:github',
|
name: 'misskey:authentication:github',
|
||||||
value: `${links.githubId}@${links.githubLogin}`
|
value: `${profile.githubId}@${profile.githubLogin}`
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (links.discord) {
|
if (profile.discord) {
|
||||||
attachment.push({
|
attachment.push({
|
||||||
type: 'PropertyValue',
|
type: 'PropertyValue',
|
||||||
name: 'Discord',
|
name: 'Discord',
|
||||||
value: `<a href="https://discordapp.com/users/${links.discordId}" rel="me nofollow noopener" target="_blank"><span>${links.discordUsername}#${links.discordDiscriminator}</span></a>`,
|
value: `<a href="https://discordapp.com/users/${profile.discordId}" rel="me nofollow noopener" target="_blank"><span>${profile.discordUsername}#${profile.discordDiscriminator}</span></a>`,
|
||||||
identifier: {
|
identifier: {
|
||||||
type: 'PropertyValue',
|
type: 'PropertyValue',
|
||||||
name: 'misskey:authentication:discord',
|
name: 'misskey:authentication:discord',
|
||||||
value: `${links.discordId}@${links.discordUsername}#${links.discordDiscriminator}`
|
value: `${profile.discordId}@${profile.discordUsername}#${profile.discordDiscriminator}`
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ export async function renderPerson(user: ILocalUser) {
|
||||||
url: `${config.url}/@${user.username}`,
|
url: `${config.url}/@${user.username}`,
|
||||||
preferredUsername: user.username,
|
preferredUsername: user.username,
|
||||||
name: user.name,
|
name: user.name,
|
||||||
summary: toHtml(parse(user.description)),
|
summary: toHtml(parse(profile.description)),
|
||||||
icon: user.avatarId && renderImage(avatar),
|
icon: user.avatarId && renderImage(avatar),
|
||||||
image: user.bannerId && renderImage(banner),
|
image: user.bannerId && renderImage(banner),
|
||||||
tag,
|
tag,
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { ID } from '../../../../misc/cafy-id';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import * as bcrypt from 'bcryptjs';
|
import * as bcrypt from 'bcryptjs';
|
||||||
import rndstr from 'rndstr';
|
import rndstr from 'rndstr';
|
||||||
import { Users } from '../../../../models';
|
import { Users, UserProfiles } from '../../../../models';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
desc: {
|
desc: {
|
||||||
|
@ -42,7 +42,9 @@ export default define(meta, async (ps) => {
|
||||||
// Generate hash of password
|
// Generate hash of password
|
||||||
const hash = bcrypt.hashSync(passwd);
|
const hash = bcrypt.hashSync(passwd);
|
||||||
|
|
||||||
await Users.update(user.id, {
|
await UserProfiles.update({
|
||||||
|
userId: user.id
|
||||||
|
}, {
|
||||||
password: hash
|
password: hash
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import * as speakeasy from 'speakeasy';
|
import * as speakeasy from 'speakeasy';
|
||||||
import define from '../../../define';
|
import define from '../../../define';
|
||||||
import { Users } from '../../../../../models';
|
import { UserProfiles } from '../../../../../models';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
|
@ -16,24 +16,26 @@ export const meta = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps, user) => {
|
export default define(meta, async (ps, user) => {
|
||||||
const _token = ps.token.replace(/\s/g, '');
|
const token = ps.token.replace(/\s/g, '');
|
||||||
|
|
||||||
if (user.twoFactorTempSecret == null) {
|
const profile = await UserProfiles.findOne({ userId: user.id });
|
||||||
|
|
||||||
|
if (profile.twoFactorTempSecret == null) {
|
||||||
throw new Error('二段階認証の設定が開始されていません');
|
throw new Error('二段階認証の設定が開始されていません');
|
||||||
}
|
}
|
||||||
|
|
||||||
const verified = (speakeasy as any).totp.verify({
|
const verified = (speakeasy as any).totp.verify({
|
||||||
secret: user.twoFactorTempSecret,
|
secret: profile.twoFactorTempSecret,
|
||||||
encoding: 'base32',
|
encoding: 'base32',
|
||||||
token: _token
|
token: token
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!verified) {
|
if (!verified) {
|
||||||
throw new Error('not verified');
|
throw new Error('not verified');
|
||||||
}
|
}
|
||||||
|
|
||||||
await Users.update(user.id, {
|
await UserProfiles.update({ userId: user.id }, {
|
||||||
twoFactorSecret: user.twoFactorTempSecret,
|
twoFactorSecret: profile.twoFactorTempSecret,
|
||||||
twoFactorEnabled: true
|
twoFactorEnabled: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as speakeasy from 'speakeasy';
|
||||||
import * as QRCode from 'qrcode';
|
import * as QRCode from 'qrcode';
|
||||||
import config from '../../../../../config';
|
import config from '../../../../../config';
|
||||||
import define from '../../../define';
|
import define from '../../../define';
|
||||||
import { Users } from '../../../../../models';
|
import { UserProfiles } from '../../../../../models';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
|
@ -19,8 +19,10 @@ export const meta = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps, user) => {
|
export default define(meta, async (ps, user) => {
|
||||||
|
const profile = await UserProfiles.findOne({ userId: user.id });
|
||||||
|
|
||||||
// Compare password
|
// Compare password
|
||||||
const same = await bcrypt.compare(ps.password, user.password);
|
const same = await bcrypt.compare(ps.password, profile.password);
|
||||||
|
|
||||||
if (!same) {
|
if (!same) {
|
||||||
throw new Error('incorrect password');
|
throw new Error('incorrect password');
|
||||||
|
@ -31,7 +33,7 @@ export default define(meta, async (ps, user) => {
|
||||||
length: 32
|
length: 32
|
||||||
});
|
});
|
||||||
|
|
||||||
await Users.update(user.id, {
|
await UserProfiles.update({ userId: user.id }, {
|
||||||
twoFactorTempSecret: secret.base32
|
twoFactorTempSecret: secret.base32
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import * as bcrypt from 'bcryptjs';
|
import * as bcrypt from 'bcryptjs';
|
||||||
import define from '../../../define';
|
import define from '../../../define';
|
||||||
import { Users } from '../../../../../models';
|
import { UserProfiles } from '../../../../../models';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
|
@ -16,17 +16,17 @@ export const meta = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps, user) => {
|
export default define(meta, async (ps, user) => {
|
||||||
|
const profile = await UserProfiles.findOne({ userId: user.id });
|
||||||
|
|
||||||
// Compare password
|
// Compare password
|
||||||
const same = await bcrypt.compare(ps.password, user.password);
|
const same = await bcrypt.compare(ps.password, profile.password);
|
||||||
|
|
||||||
if (!same) {
|
if (!same) {
|
||||||
throw new Error('incorrect password');
|
throw new Error('incorrect password');
|
||||||
}
|
}
|
||||||
|
|
||||||
await Users.update(user.id, {
|
await UserProfiles.update({ userId: user.id }, {
|
||||||
twoFactorSecret: null,
|
twoFactorSecret: null,
|
||||||
twoFactorEnabled: false
|
twoFactorEnabled: false
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import * as bcrypt from 'bcryptjs';
|
import * as bcrypt from 'bcryptjs';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { Users } from '../../../../models';
|
import { UserProfiles } from '../../../../models';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
|
@ -20,8 +20,10 @@ export const meta = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps, user) => {
|
export default define(meta, async (ps, user) => {
|
||||||
|
const profile = await UserProfiles.findOne({ userId: user.id });
|
||||||
|
|
||||||
// Compare password
|
// Compare password
|
||||||
const same = await bcrypt.compare(ps.currentPassword, user.password);
|
const same = await bcrypt.compare(ps.currentPassword, profile.password);
|
||||||
|
|
||||||
if (!same) {
|
if (!same) {
|
||||||
throw new Error('incorrect password');
|
throw new Error('incorrect password');
|
||||||
|
@ -31,7 +33,7 @@ export default define(meta, async (ps, user) => {
|
||||||
const salt = await bcrypt.genSalt(8);
|
const salt = await bcrypt.genSalt(8);
|
||||||
const hash = await bcrypt.hash(ps.newPassword, salt);
|
const hash = await bcrypt.hash(ps.newPassword, salt);
|
||||||
|
|
||||||
await Users.update(user.id, {
|
await UserProfiles.update({ userId: user.id }, {
|
||||||
password: hash
|
password: hash
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import * as bcrypt from 'bcryptjs';
|
import * as bcrypt from 'bcryptjs';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { Users } from '../../../../models';
|
import { Users, UserProfiles } from '../../../../models';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
|
@ -16,8 +16,10 @@ export const meta = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps, user) => {
|
export default define(meta, async (ps, user) => {
|
||||||
|
const profile = await UserProfiles.findOne({ userId: user.id });
|
||||||
|
|
||||||
// Compare password
|
// Compare password
|
||||||
const same = await bcrypt.compare(ps.password, user.password);
|
const same = await bcrypt.compare(ps.password, profile.password);
|
||||||
|
|
||||||
if (!same) {
|
if (!same) {
|
||||||
throw new Error('incorrect password');
|
throw new Error('incorrect password');
|
||||||
|
|
|
@ -3,7 +3,7 @@ import * as bcrypt from 'bcryptjs';
|
||||||
import { publishMainStream } from '../../../../services/stream';
|
import { publishMainStream } from '../../../../services/stream';
|
||||||
import generateUserToken from '../../common/generate-native-user-token';
|
import generateUserToken from '../../common/generate-native-user-token';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { Users } from '../../../../models';
|
import { Users, UserProfiles } from '../../../../models';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
|
@ -18,8 +18,10 @@ export const meta = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps, user) => {
|
export default define(meta, async (ps, user) => {
|
||||||
|
const profile = await UserProfiles.findOne({ userId: user.id });
|
||||||
|
|
||||||
// Compare password
|
// Compare password
|
||||||
const same = await bcrypt.compare(ps.password, user.password);
|
const same = await bcrypt.compare(ps.password, profile.password);
|
||||||
|
|
||||||
if (!same) {
|
if (!same) {
|
||||||
throw new Error('incorrect password');
|
throw new Error('incorrect password');
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import { publishMainStream } from '../../../../services/stream';
|
import { publishMainStream } from '../../../../services/stream';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { Users } from '../../../../models';
|
import { UserProfiles } from '../../../../models';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
|
@ -20,7 +20,7 @@ export const meta = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps, user) => {
|
export default define(meta, async (ps, user) => {
|
||||||
await Users.createQueryBuilder().update()
|
await UserProfiles.createQueryBuilder().update()
|
||||||
.set({
|
.set({
|
||||||
clientData: {
|
clientData: {
|
||||||
[ps.name]: ps.value
|
[ps.name]: ps.value
|
||||||
|
|
|
@ -8,7 +8,7 @@ import config from '../../../../config';
|
||||||
import * as ms from 'ms';
|
import * as ms from 'ms';
|
||||||
import * as bcrypt from 'bcryptjs';
|
import * as bcrypt from 'bcryptjs';
|
||||||
import { apiLogger } from '../../logger';
|
import { apiLogger } from '../../logger';
|
||||||
import { Users } from '../../../../models';
|
import { Users, UserProfiles } from '../../../../models';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
|
@ -32,14 +32,16 @@ export const meta = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps, user) => {
|
export default define(meta, async (ps, user) => {
|
||||||
|
const profile = await UserProfiles.findOne({ userId: user.id });
|
||||||
|
|
||||||
// Compare password
|
// Compare password
|
||||||
const same = await bcrypt.compare(ps.password, user.password);
|
const same = await bcrypt.compare(ps.password, profile.password);
|
||||||
|
|
||||||
if (!same) {
|
if (!same) {
|
||||||
throw new Error('incorrect password');
|
throw new Error('incorrect password');
|
||||||
}
|
}
|
||||||
|
|
||||||
await Users.update(user.id, {
|
await UserProfiles.update({ userId: user.id }, {
|
||||||
email: ps.email,
|
email: ps.email,
|
||||||
emailVerified: false,
|
emailVerified: false,
|
||||||
emailVerifyCode: null
|
emailVerifyCode: null
|
||||||
|
@ -56,7 +58,7 @@ export default define(meta, async (ps, user) => {
|
||||||
if (ps.email != null) {
|
if (ps.email != null) {
|
||||||
const code = rndstr('a-z0-9', 16);
|
const code = rndstr('a-z0-9', 16);
|
||||||
|
|
||||||
await Users.update(user.id, {
|
await UserProfiles.update({ userId: user.id }, {
|
||||||
emailVerifyCode: code
|
emailVerifyCode: code
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,9 @@ import extractHashtags from '../../../../misc/extract-hashtags';
|
||||||
import * as langmap from 'langmap';
|
import * as langmap from 'langmap';
|
||||||
import { updateHashtag } from '../../../../services/update-hashtag';
|
import { updateHashtag } from '../../../../services/update-hashtag';
|
||||||
import { ApiError } from '../../error';
|
import { ApiError } from '../../error';
|
||||||
import { Users, DriveFiles } from '../../../../models';
|
import { Users, DriveFiles, UserProfiles } from '../../../../models';
|
||||||
|
import { User } from '../../../../models/entities/user';
|
||||||
|
import { UserProfile } from '../../../../models/entities/user-profile';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
desc: {
|
desc: {
|
||||||
|
@ -154,22 +156,23 @@ export const meta = {
|
||||||
export default define(meta, async (ps, user, app) => {
|
export default define(meta, async (ps, user, app) => {
|
||||||
const isSecure = user != null && app == null;
|
const isSecure = user != null && app == null;
|
||||||
|
|
||||||
const updates = {} as any;
|
const updates = {} as Partial<User>;
|
||||||
|
const profile = {} as Partial<UserProfile>;
|
||||||
|
|
||||||
if (ps.name !== undefined) updates.name = ps.name;
|
if (ps.name !== undefined) updates.name = ps.name;
|
||||||
if (ps.description !== undefined) updates.description = ps.description;
|
if (ps.description !== undefined) profile.description = ps.description;
|
||||||
if (ps.lang !== undefined) updates.lang = ps.lang;
|
//if (ps.lang !== undefined) updates.lang = ps.lang;
|
||||||
if (ps.location !== undefined) updates.location = ps.location;
|
if (ps.location !== undefined) profile.location = ps.location;
|
||||||
if (ps.birthday !== undefined) updates.birthday = ps.birthday;
|
if (ps.birthday !== undefined) profile.birthday = ps.birthday;
|
||||||
if (ps.avatarId !== undefined) updates.avatarId = ps.avatarId;
|
if (ps.avatarId !== undefined) updates.avatarId = ps.avatarId;
|
||||||
if (ps.bannerId !== undefined) updates.bannerId = ps.bannerId;
|
if (ps.bannerId !== undefined) updates.bannerId = ps.bannerId;
|
||||||
if (typeof ps.isLocked == 'boolean') updates.isLocked = ps.isLocked;
|
if (typeof ps.isLocked == 'boolean') updates.isLocked = ps.isLocked;
|
||||||
if (typeof ps.isBot == 'boolean') updates.isBot = ps.isBot;
|
if (typeof ps.isBot == 'boolean') updates.isBot = ps.isBot;
|
||||||
if (typeof ps.carefulBot == 'boolean') updates.carefulBot = ps.carefulBot;
|
if (typeof ps.carefulBot == 'boolean') profile.carefulBot = ps.carefulBot;
|
||||||
if (typeof ps.autoAcceptFollowed == 'boolean') updates.autoAcceptFollowed = ps.autoAcceptFollowed;
|
if (typeof ps.autoAcceptFollowed == 'boolean') profile.autoAcceptFollowed = ps.autoAcceptFollowed;
|
||||||
if (typeof ps.isCat == 'boolean') updates.isCat = ps.isCat;
|
if (typeof ps.isCat == 'boolean') updates.isCat = ps.isCat;
|
||||||
if (typeof ps.autoWatch == 'boolean') updates.autoWatch = ps.autoWatch;
|
if (typeof ps.autoWatch == 'boolean') profile.autoWatch = ps.autoWatch;
|
||||||
if (typeof ps.alwaysMarkNsfw == 'boolean') updates.alwaysMarkNsfw = ps.alwaysMarkNsfw;
|
if (typeof ps.alwaysMarkNsfw == 'boolean') profile.alwaysMarkNsfw = ps.alwaysMarkNsfw;
|
||||||
|
|
||||||
if (ps.avatarId) {
|
if (ps.avatarId) {
|
||||||
const avatar = await DriveFiles.findOne(ps.avatarId);
|
const avatar = await DriveFiles.findOne(ps.avatarId);
|
||||||
|
@ -206,8 +209,8 @@ export default define(meta, async (ps, user, app) => {
|
||||||
emojis = emojis.concat(extractEmojis(tokens));
|
emojis = emojis.concat(extractEmojis(tokens));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updates.description != null) {
|
if (profile.description != null) {
|
||||||
const tokens = parse(updates.description);
|
const tokens = parse(profile.description);
|
||||||
emojis = emojis.concat(extractEmojis(tokens));
|
emojis = emojis.concat(extractEmojis(tokens));
|
||||||
tags = extractHashtags(tokens).map(tag => tag.toLowerCase());
|
tags = extractHashtags(tokens).map(tag => tag.toLowerCase());
|
||||||
}
|
}
|
||||||
|
@ -221,6 +224,7 @@ export default define(meta, async (ps, user, app) => {
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
await Users.update(user.id, updates);
|
await Users.update(user.id, updates);
|
||||||
|
await UserProfiles.update({ userId: user.id }, profile);
|
||||||
|
|
||||||
const iObj = await Users.pack(user.id, user, {
|
const iObj = await Users.pack(user.id, user, {
|
||||||
detail: true,
|
detail: true,
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { deliver } from '../../../../../queue';
|
||||||
import { renderActivity } from '../../../../../remote/activitypub/renderer';
|
import { renderActivity } from '../../../../../remote/activitypub/renderer';
|
||||||
import renderVote from '../../../../../remote/activitypub/renderer/vote';
|
import renderVote from '../../../../../remote/activitypub/renderer/vote';
|
||||||
import { deliverQuestionUpdate } from '../../../../../services/note/polls/update';
|
import { deliverQuestionUpdate } from '../../../../../services/note/polls/update';
|
||||||
import { PollVotes, NoteWatchings, Users, Polls } from '../../../../../models';
|
import { PollVotes, NoteWatchings, Users, Polls, UserProfiles } from '../../../../../models';
|
||||||
import { Not } from 'typeorm';
|
import { Not } from 'typeorm';
|
||||||
import { IRemoteUser } from '../../../../../models/entities/user';
|
import { IRemoteUser } from '../../../../../models/entities/user';
|
||||||
import { genId } from '../../../../../misc/gen-id';
|
import { genId } from '../../../../../misc/gen-id';
|
||||||
|
@ -149,8 +149,10 @@ export default define(meta, async (ps, user) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const profile = await UserProfiles.findOne({ userId: user.id });
|
||||||
|
|
||||||
// この投稿をWatchする
|
// この投稿をWatchする
|
||||||
if (user.autoWatch !== false) {
|
if (profile.autoWatch !== false) {
|
||||||
watch(user.id, note);
|
watch(user.id, note);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as speakeasy from 'speakeasy';
|
||||||
import { publishMainStream } from '../../../services/stream';
|
import { publishMainStream } from '../../../services/stream';
|
||||||
import signin from '../common/signin';
|
import signin from '../common/signin';
|
||||||
import config from '../../../config';
|
import config from '../../../config';
|
||||||
import { Users, Signins } from '../../../models';
|
import { Users, Signins, UserProfiles } from '../../../models';
|
||||||
import { ILocalUser } from '../../../models/entities/user';
|
import { ILocalUser } from '../../../models/entities/user';
|
||||||
import { genId } from '../../../misc/gen-id';
|
import { genId } from '../../../misc/gen-id';
|
||||||
|
|
||||||
|
@ -45,13 +45,15 @@ export default async (ctx: Koa.BaseContext) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const profile = await UserProfiles.findOne({ userId: user.id });
|
||||||
|
|
||||||
// Compare password
|
// Compare password
|
||||||
const same = await bcrypt.compare(password, user.password);
|
const same = await bcrypt.compare(password, profile.password);
|
||||||
|
|
||||||
if (same) {
|
if (same) {
|
||||||
if (user.twoFactorEnabled) {
|
if (profile.twoFactorEnabled) {
|
||||||
const verified = (speakeasy as any).totp.verify({
|
const verified = (speakeasy as any).totp.verify({
|
||||||
secret: user.twoFactorSecret,
|
secret: profile.twoFactorSecret,
|
||||||
encoding: 'base32',
|
encoding: 'base32',
|
||||||
token: token
|
token: token
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,13 +5,13 @@ import generateUserToken from '../common/generate-native-user-token';
|
||||||
import config from '../../../config';
|
import config from '../../../config';
|
||||||
import fetchMeta from '../../../misc/fetch-meta';
|
import fetchMeta from '../../../misc/fetch-meta';
|
||||||
import * as recaptcha from 'recaptcha-promise';
|
import * as recaptcha from 'recaptcha-promise';
|
||||||
import { Users, RegistrationTickets, UserServiceLinkings, UserKeypairs } from '../../../models';
|
import { Users, RegistrationTickets, UserProfiles, UserKeypairs } from '../../../models';
|
||||||
import { genId } from '../../../misc/gen-id';
|
import { genId } from '../../../misc/gen-id';
|
||||||
import { usersChart } from '../../../services/chart';
|
import { usersChart } from '../../../services/chart';
|
||||||
import { UserServiceLinking } from '../../../models/entities/user-service-linking';
|
|
||||||
import { User } from '../../../models/entities/user';
|
import { User } from '../../../models/entities/user';
|
||||||
import { UserKeypair } from '../../../models/entities/user-keypair';
|
import { UserKeypair } from '../../../models/entities/user-keypair';
|
||||||
import { toPuny } from '../../../misc/convert-host';
|
import { toPuny } from '../../../misc/convert-host';
|
||||||
|
import { UserProfile } from '../../../models/entities/user-profile';
|
||||||
|
|
||||||
export default async (ctx: Koa.BaseContext) => {
|
export default async (ctx: Koa.BaseContext) => {
|
||||||
const body = ctx.request.body as any;
|
const body = ctx.request.body as any;
|
||||||
|
@ -106,23 +106,21 @@ export default async (ctx: Koa.BaseContext) => {
|
||||||
usernameLower: username.toLowerCase(),
|
usernameLower: username.toLowerCase(),
|
||||||
host: toPuny(host),
|
host: toPuny(host),
|
||||||
token: secret,
|
token: secret,
|
||||||
password: hash,
|
|
||||||
isAdmin: config.autoAdmin && usersCount === 0,
|
isAdmin: config.autoAdmin && usersCount === 0,
|
||||||
autoAcceptFollowed: true,
|
|
||||||
autoWatch: false
|
|
||||||
} as User);
|
} as User);
|
||||||
|
|
||||||
await UserKeypairs.save({
|
await UserKeypairs.save({
|
||||||
id: genId(),
|
|
||||||
publicKey: keyPair[0],
|
publicKey: keyPair[0],
|
||||||
privateKey: keyPair[1],
|
privateKey: keyPair[1],
|
||||||
userId: account.id
|
userId: account.id
|
||||||
} as UserKeypair);
|
} as UserKeypair);
|
||||||
|
|
||||||
await UserServiceLinkings.save({
|
await UserProfiles.save({
|
||||||
id: genId(),
|
userId: account.id,
|
||||||
userId: account.id
|
autoAcceptFollowed: true,
|
||||||
} as UserServiceLinking);
|
autoWatch: false,
|
||||||
|
password: hash,
|
||||||
|
} as Partial<UserProfile>);
|
||||||
|
|
||||||
usersChart.update(account, true);
|
usersChart.update(account, true);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import redis from '../../../db/redis';
|
||||||
import * as uuid from 'uuid';
|
import * as uuid from 'uuid';
|
||||||
import signin from '../common/signin';
|
import signin from '../common/signin';
|
||||||
import fetchMeta from '../../../misc/fetch-meta';
|
import fetchMeta from '../../../misc/fetch-meta';
|
||||||
import { Users, UserServiceLinkings } from '../../../models';
|
import { Users, UserProfiles } from '../../../models';
|
||||||
import { ILocalUser } from '../../../models/entities/user';
|
import { ILocalUser } from '../../../models/entities/user';
|
||||||
|
|
||||||
function getUserToken(ctx: Koa.BaseContext) {
|
function getUserToken(ctx: Koa.BaseContext) {
|
||||||
|
@ -45,7 +45,7 @@ router.get('/disconnect/discord', async ctx => {
|
||||||
token: userToken
|
token: userToken
|
||||||
});
|
});
|
||||||
|
|
||||||
await UserServiceLinkings.update({
|
await UserProfiles.update({
|
||||||
userId: user.id
|
userId: user.id
|
||||||
}, {
|
}, {
|
||||||
discord: false,
|
discord: false,
|
||||||
|
@ -202,7 +202,7 @@ router.get('/dc/cb', async ctx => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const link = await UserServiceLinkings.createQueryBuilder()
|
const profile = await UserProfiles.createQueryBuilder()
|
||||||
.where('discord @> :discord', {
|
.where('discord @> :discord', {
|
||||||
discord: {
|
discord: {
|
||||||
id: id,
|
id: id,
|
||||||
|
@ -211,12 +211,12 @@ router.get('/dc/cb', async ctx => {
|
||||||
.andWhere('userHost IS NULL')
|
.andWhere('userHost IS NULL')
|
||||||
.getOne();
|
.getOne();
|
||||||
|
|
||||||
if (link == null) {
|
if (profile == null) {
|
||||||
ctx.throw(404, `@${username}#${discriminator}と連携しているMisskeyアカウントはありませんでした...`);
|
ctx.throw(404, `@${username}#${discriminator}と連携しているMisskeyアカウントはありませんでした...`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await UserServiceLinkings.update(link.id, {
|
await UserProfiles.update({ userId: profile.userId }, {
|
||||||
discord: true,
|
discord: true,
|
||||||
discordAccessToken: accessToken,
|
discordAccessToken: accessToken,
|
||||||
discordRefreshToken: refreshToken,
|
discordRefreshToken: refreshToken,
|
||||||
|
@ -225,7 +225,7 @@ router.get('/dc/cb', async ctx => {
|
||||||
discordDiscriminator: discriminator
|
discordDiscriminator: discriminator
|
||||||
});
|
});
|
||||||
|
|
||||||
signin(ctx, await Users.findOne(link.userId) as ILocalUser, true);
|
signin(ctx, await Users.findOne(profile.userId) as ILocalUser, true);
|
||||||
} else {
|
} else {
|
||||||
const code = ctx.query.code;
|
const code = ctx.query.code;
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ router.get('/dc/cb', async ctx => {
|
||||||
token: userToken
|
token: userToken
|
||||||
});
|
});
|
||||||
|
|
||||||
await UserServiceLinkings.update({ userId: user.id }, {
|
await UserProfiles.update({ userId: user.id }, {
|
||||||
discord: true,
|
discord: true,
|
||||||
discordAccessToken: accessToken,
|
discordAccessToken: accessToken,
|
||||||
discordRefreshToken: refreshToken,
|
discordRefreshToken: refreshToken,
|
||||||
|
|
|
@ -8,7 +8,7 @@ import redis from '../../../db/redis';
|
||||||
import * as uuid from 'uuid';
|
import * as uuid from 'uuid';
|
||||||
import signin from '../common/signin';
|
import signin from '../common/signin';
|
||||||
import fetchMeta from '../../../misc/fetch-meta';
|
import fetchMeta from '../../../misc/fetch-meta';
|
||||||
import { Users, UserServiceLinkings } from '../../../models';
|
import { Users, UserProfiles } from '../../../models';
|
||||||
import { ILocalUser } from '../../../models/entities/user';
|
import { ILocalUser } from '../../../models/entities/user';
|
||||||
|
|
||||||
function getUserToken(ctx: Koa.BaseContext) {
|
function getUserToken(ctx: Koa.BaseContext) {
|
||||||
|
@ -45,7 +45,7 @@ router.get('/disconnect/github', async ctx => {
|
||||||
token: userToken
|
token: userToken
|
||||||
});
|
});
|
||||||
|
|
||||||
await UserServiceLinkings.update({
|
await UserProfiles.update({
|
||||||
userId: user.id
|
userId: user.id
|
||||||
}, {
|
}, {
|
||||||
github: false,
|
github: false,
|
||||||
|
@ -191,7 +191,7 @@ router.get('/gh/cb', async ctx => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const link = await UserServiceLinkings.createQueryBuilder()
|
const link = await UserProfiles.createQueryBuilder()
|
||||||
.where('github @> :github', {
|
.where('github @> :github', {
|
||||||
github: {
|
github: {
|
||||||
id: id,
|
id: id,
|
||||||
|
@ -263,7 +263,7 @@ router.get('/gh/cb', async ctx => {
|
||||||
token: userToken
|
token: userToken
|
||||||
});
|
});
|
||||||
|
|
||||||
await UserServiceLinkings.update({ userId: user.id }, {
|
await UserProfiles.update({ userId: user.id }, {
|
||||||
github: true,
|
github: true,
|
||||||
githubAccessToken: accessToken,
|
githubAccessToken: accessToken,
|
||||||
githubId: id,
|
githubId: id,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { publishMainStream } from '../../../services/stream';
|
||||||
import config from '../../../config';
|
import config from '../../../config';
|
||||||
import signin from '../common/signin';
|
import signin from '../common/signin';
|
||||||
import fetchMeta from '../../../misc/fetch-meta';
|
import fetchMeta from '../../../misc/fetch-meta';
|
||||||
import { Users, UserServiceLinkings } from '../../../models';
|
import { Users, UserProfiles } from '../../../models';
|
||||||
import { ILocalUser } from '../../../models/entities/user';
|
import { ILocalUser } from '../../../models/entities/user';
|
||||||
|
|
||||||
function getUserToken(ctx: Koa.BaseContext) {
|
function getUserToken(ctx: Koa.BaseContext) {
|
||||||
|
@ -44,7 +44,7 @@ router.get('/disconnect/twitter', async ctx => {
|
||||||
token: userToken
|
token: userToken
|
||||||
});
|
});
|
||||||
|
|
||||||
await UserServiceLinkings.update({
|
await UserProfiles.update({
|
||||||
userId: user.id
|
userId: user.id
|
||||||
}, {
|
}, {
|
||||||
twitter: false,
|
twitter: false,
|
||||||
|
@ -139,7 +139,7 @@ router.get('/tw/cb', async ctx => {
|
||||||
|
|
||||||
const result = await twAuth.done(JSON.parse(twCtx), ctx.query.oauth_verifier);
|
const result = await twAuth.done(JSON.parse(twCtx), ctx.query.oauth_verifier);
|
||||||
|
|
||||||
const link = await UserServiceLinkings.createQueryBuilder()
|
const link = await UserProfiles.createQueryBuilder()
|
||||||
.where('twitter @> :twitter', {
|
.where('twitter @> :twitter', {
|
||||||
twitter: {
|
twitter: {
|
||||||
userId: result.userId,
|
userId: result.userId,
|
||||||
|
@ -177,7 +177,7 @@ router.get('/tw/cb', async ctx => {
|
||||||
token: userToken
|
token: userToken
|
||||||
});
|
});
|
||||||
|
|
||||||
await UserServiceLinkings.update({ userId: user.id }, {
|
await UserProfiles.update({ userId: user.id }, {
|
||||||
twitter: true,
|
twitter: true,
|
||||||
twitterAccessToken: result.accessToken,
|
twitterAccessToken: result.accessToken,
|
||||||
twitterAccessTokenSecret: result.accessTokenSecret,
|
twitterAccessTokenSecret: result.accessTokenSecret,
|
||||||
|
|
|
@ -23,7 +23,7 @@ import apiServer from './api';
|
||||||
import { sum } from '../prelude/array';
|
import { sum } from '../prelude/array';
|
||||||
import Logger from '../services/logger';
|
import Logger from '../services/logger';
|
||||||
import { program } from '../argv';
|
import { program } from '../argv';
|
||||||
import { Users } from '../models';
|
import { UserProfiles } from '../models';
|
||||||
import { networkChart } from '../services/chart';
|
import { networkChart } from '../services/chart';
|
||||||
|
|
||||||
export const serverLogger = new Logger('server', 'gray', false);
|
export const serverLogger = new Logger('server', 'gray', false);
|
||||||
|
@ -73,15 +73,15 @@ router.use(nodeinfo.routes());
|
||||||
router.use(wellKnown.routes());
|
router.use(wellKnown.routes());
|
||||||
|
|
||||||
router.get('/verify-email/:code', async ctx => {
|
router.get('/verify-email/:code', async ctx => {
|
||||||
const user = await Users.findOne({
|
const profile = await UserProfiles.findOne({
|
||||||
emailVerifyCode: ctx.params.code
|
emailVerifyCode: ctx.params.code
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user != null) {
|
if (profile != null) {
|
||||||
ctx.body = 'Verify succeeded!';
|
ctx.body = 'Verify succeeded!';
|
||||||
ctx.status = 200;
|
ctx.status = 200;
|
||||||
|
|
||||||
Users.update(user.id, {
|
UserProfiles.update({ userId: profile.userId }, {
|
||||||
emailVerified: true,
|
emailVerified: true,
|
||||||
emailVerifyCode: null
|
emailVerifyCode: null
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Feed } from 'feed';
|
import { Feed } from 'feed';
|
||||||
import config from '../../config';
|
import config from '../../config';
|
||||||
import { User } from '../../models/entities/user';
|
import { User } from '../../models/entities/user';
|
||||||
import { Notes, DriveFiles } from '../../models';
|
import { Notes, DriveFiles, UserProfiles } from '../../models';
|
||||||
import { In } from 'typeorm';
|
import { In } from 'typeorm';
|
||||||
|
|
||||||
export default async function(user: User) {
|
export default async function(user: User) {
|
||||||
|
@ -10,6 +10,8 @@ export default async function(user: User) {
|
||||||
name: user.name || user.username
|
name: user.name || user.username
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const profile = await UserProfiles.findOne({ userId: user.id });
|
||||||
|
|
||||||
const notes = await Notes.find({
|
const notes = await Notes.find({
|
||||||
where: {
|
where: {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
|
@ -25,7 +27,7 @@ export default async function(user: User) {
|
||||||
title: `${author.name} (@${user.username}@${config.host})`,
|
title: `${author.name} (@${user.username}@${config.host})`,
|
||||||
updated: notes[0].createdAt,
|
updated: notes[0].createdAt,
|
||||||
generator: 'Misskey',
|
generator: 'Misskey',
|
||||||
description: `${user.notesCount} Notes, ${user.followingCount} Following, ${user.followersCount} Followers${user.description ? ` · ${user.description}` : ''}`,
|
description: `${user.notesCount} Notes, ${user.followingCount} Following, ${user.followersCount} Followers${profile.description ? ` · ${profile.description}` : ''}`,
|
||||||
link: author.link,
|
link: author.link,
|
||||||
image: user.avatarUrl,
|
image: user.avatarUrl,
|
||||||
feedLinks: {
|
feedLinks: {
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { driveLogger } from './logger';
|
||||||
import { IImage, ConvertToJpeg, ConvertToWebp, ConvertToPng } from './image-processor';
|
import { IImage, ConvertToJpeg, ConvertToWebp, ConvertToPng } from './image-processor';
|
||||||
import { contentDisposition } from '../../misc/content-disposition';
|
import { contentDisposition } from '../../misc/content-disposition';
|
||||||
import { detectMine } from '../../misc/detect-mine';
|
import { detectMine } from '../../misc/detect-mine';
|
||||||
import { DriveFiles, DriveFolders, Users, Instances } from '../../models';
|
import { DriveFiles, DriveFolders, Users, Instances, UserProfiles } from '../../models';
|
||||||
import { InternalStorage } from './internal-storage';
|
import { InternalStorage } from './internal-storage';
|
||||||
import { DriveFile } from '../../models/entities/drive-file';
|
import { DriveFile } from '../../models/entities/drive-file';
|
||||||
import { IRemoteUser, User } from '../../models/entities/user';
|
import { IRemoteUser, User } from '../../models/entities/user';
|
||||||
|
@ -365,6 +365,8 @@ export default async function(
|
||||||
propPromises = [calcWh(), calcAvg()];
|
propPromises = [calcWh(), calcAvg()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const profile = await UserProfiles.findOne({ userId: user.id });
|
||||||
|
|
||||||
const [folder] = await Promise.all([fetchFolder(), Promise.all(propPromises)]);
|
const [folder] = await Promise.all([fetchFolder(), Promise.all(propPromises)]);
|
||||||
|
|
||||||
let file = new DriveFile();
|
let file = new DriveFile();
|
||||||
|
@ -376,7 +378,7 @@ export default async function(
|
||||||
file.comment = comment;
|
file.comment = comment;
|
||||||
file.properties = properties;
|
file.properties = properties;
|
||||||
file.isLink = isLink;
|
file.isLink = isLink;
|
||||||
file.isSensitive = Users.isLocalUser(user) && user.alwaysMarkNsfw ? true :
|
file.isSensitive = Users.isLocalUser(user) && profile.alwaysMarkNsfw ? true :
|
||||||
(sensitive !== null && sensitive !== undefined)
|
(sensitive !== null && sensitive !== undefined)
|
||||||
? sensitive
|
? sensitive
|
||||||
: false;
|
: false;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { registerOrFetchInstanceDoc } from '../register-or-fetch-instance-doc';
|
||||||
import Logger from '../logger';
|
import Logger from '../logger';
|
||||||
import { IdentifiableError } from '../../misc/identifiable-error';
|
import { IdentifiableError } from '../../misc/identifiable-error';
|
||||||
import { User } from '../../models/entities/user';
|
import { User } from '../../models/entities/user';
|
||||||
import { Followings, Users, FollowRequests, Blockings, Instances } from '../../models';
|
import { Followings, Users, FollowRequests, Blockings, Instances, UserProfiles } from '../../models';
|
||||||
import { instanceChart, perUserFollowingChart } from '../chart';
|
import { instanceChart, perUserFollowingChart } from '../chart';
|
||||||
import { genId } from '../../misc/gen-id';
|
import { genId } from '../../misc/gen-id';
|
||||||
import { createNotification } from '../create-notification';
|
import { createNotification } from '../create-notification';
|
||||||
|
@ -115,11 +115,13 @@ export default async function(follower: User, followee: User, requestId?: string
|
||||||
if (blocked != null) throw new IdentifiableError('3338392a-f764-498d-8855-db939dcf8c48', 'blocked');
|
if (blocked != null) throw new IdentifiableError('3338392a-f764-498d-8855-db939dcf8c48', 'blocked');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const followeeProfile = await UserProfiles.findOne({ userId: followee.id });
|
||||||
|
|
||||||
// フォロー対象が鍵アカウントである or
|
// フォロー対象が鍵アカウントである or
|
||||||
// フォロワーがBotであり、フォロー対象がBotからのフォローに慎重である or
|
// フォロワーがBotであり、フォロー対象がBotからのフォローに慎重である or
|
||||||
// フォロワーがローカルユーザーであり、フォロー対象がリモートユーザーである
|
// フォロワーがローカルユーザーであり、フォロー対象がリモートユーザーである
|
||||||
// 上記のいずれかに当てはまる場合はすぐフォローせずにフォローリクエストを発行しておく
|
// 上記のいずれかに当てはまる場合はすぐフォローせずにフォローリクエストを発行しておく
|
||||||
if (followee.isLocked || (followee.carefulBot && follower.isBot) || (Users.isLocalUser(follower) && Users.isRemoteUser(followee))) {
|
if (followee.isLocked || (followeeProfile.carefulBot && follower.isBot) || (Users.isLocalUser(follower) && Users.isRemoteUser(followee))) {
|
||||||
let autoAccept = false;
|
let autoAccept = false;
|
||||||
|
|
||||||
// 鍵アカウントであっても、既にフォローされていた場合はスルー
|
// 鍵アカウントであっても、既にフォローされていた場合はスルー
|
||||||
|
@ -132,7 +134,7 @@ export default async function(follower: User, followee: User, requestId?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// フォローしているユーザーは自動承認オプション
|
// フォローしているユーザーは自動承認オプション
|
||||||
if (!autoAccept && (Users.isLocalUser(followee) && followee.autoAcceptFollowed)) {
|
if (!autoAccept && (Users.isLocalUser(followee) && followeeProfile.autoAcceptFollowed)) {
|
||||||
const followed = await Followings.findOne({
|
const followed = await Followings.findOne({
|
||||||
followerId: followee.id,
|
followerId: followee.id,
|
||||||
followeeId: follower.id
|
followeeId: follower.id
|
||||||
|
|
|
@ -17,7 +17,7 @@ import extractMentions from '../../misc/extract-mentions';
|
||||||
import extractEmojis from '../../misc/extract-emojis';
|
import extractEmojis from '../../misc/extract-emojis';
|
||||||
import extractHashtags from '../../misc/extract-hashtags';
|
import extractHashtags from '../../misc/extract-hashtags';
|
||||||
import { Note } from '../../models/entities/note';
|
import { Note } from '../../models/entities/note';
|
||||||
import { Mutings, Users, NoteWatchings, Followings, Notes, Instances, Polls } from '../../models';
|
import { Mutings, Users, NoteWatchings, Followings, Notes, Instances, Polls, UserProfiles } from '../../models';
|
||||||
import { DriveFile } from '../../models/entities/drive-file';
|
import { DriveFile } from '../../models/entities/drive-file';
|
||||||
import { App } from '../../models/entities/app';
|
import { App } from '../../models/entities/app';
|
||||||
import { Not } from 'typeorm';
|
import { Not } from 'typeorm';
|
||||||
|
@ -256,13 +256,15 @@ export default async (user: User, data: Option, silent = false) => new Promise<N
|
||||||
deliverNoteToMentionedRemoteUsers(mentionedUsers, user, noteActivity);
|
deliverNoteToMentionedRemoteUsers(mentionedUsers, user, noteActivity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const profile = await UserProfiles.findOne({ userId: user.id });
|
||||||
|
|
||||||
// If has in reply to note
|
// If has in reply to note
|
||||||
if (data.reply) {
|
if (data.reply) {
|
||||||
// Fetch watchers
|
// Fetch watchers
|
||||||
nmRelatedPromises.push(notifyToWatchersOfReplyee(data.reply, user, nm));
|
nmRelatedPromises.push(notifyToWatchersOfReplyee(data.reply, user, nm));
|
||||||
|
|
||||||
// この投稿をWatchする
|
// この投稿をWatchする
|
||||||
if (Users.isLocalUser(user) && user.autoWatch !== false) {
|
if (Users.isLocalUser(user) && profile.autoWatch) {
|
||||||
watch(user.id, data.reply);
|
watch(user.id, data.reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +288,7 @@ export default async (user: User, data: Option, silent = false) => new Promise<N
|
||||||
nmRelatedPromises.push(notifyToWatchersOfRenotee(data.renote, user, nm, type));
|
nmRelatedPromises.push(notifyToWatchersOfRenotee(data.renote, user, nm, type));
|
||||||
|
|
||||||
// この投稿をWatchする
|
// この投稿をWatchする
|
||||||
if (Users.isLocalUser(user) && user.autoWatch !== false) {
|
if (Users.isLocalUser(user) && profile.autoWatch) {
|
||||||
watch(user.id, data.renote);
|
watch(user.id, data.renote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import watch from '../../../services/note/watch';
|
||||||
import { publishNoteStream } from '../../stream';
|
import { publishNoteStream } from '../../stream';
|
||||||
import { User } from '../../../models/entities/user';
|
import { User } from '../../../models/entities/user';
|
||||||
import { Note } from '../../../models/entities/note';
|
import { Note } from '../../../models/entities/note';
|
||||||
import { PollVotes, Users, NoteWatchings, Polls } from '../../../models';
|
import { PollVotes, Users, NoteWatchings, Polls, UserProfiles } from '../../../models';
|
||||||
import { Not } from 'typeorm';
|
import { Not } from 'typeorm';
|
||||||
import { genId } from '../../../misc/gen-id';
|
import { genId } from '../../../misc/gen-id';
|
||||||
import { createNotification } from '../../create-notification';
|
import { createNotification } from '../../create-notification';
|
||||||
|
@ -67,8 +67,10 @@ export default (user: User, note: Note, choice: number) => new Promise(async (re
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const profile = await UserProfiles.findOne({ userId: user.id });
|
||||||
|
|
||||||
// ローカルユーザーが投票した場合この投稿をWatchする
|
// ローカルユーザーが投票した場合この投稿をWatchする
|
||||||
if (Users.isLocalUser(user) && user.autoWatch) {
|
if (Users.isLocalUser(user) && profile.autoWatch) {
|
||||||
watch(user.id, note);
|
watch(user.id, note);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { toDbReaction } from '../../../misc/reaction-lib';
|
||||||
import fetchMeta from '../../../misc/fetch-meta';
|
import fetchMeta from '../../../misc/fetch-meta';
|
||||||
import { User } from '../../../models/entities/user';
|
import { User } from '../../../models/entities/user';
|
||||||
import { Note } from '../../../models/entities/note';
|
import { Note } from '../../../models/entities/note';
|
||||||
import { NoteReactions, Users, NoteWatchings, Notes } from '../../../models';
|
import { NoteReactions, Users, NoteWatchings, Notes, UserProfiles } from '../../../models';
|
||||||
import { Not } from 'typeorm';
|
import { Not } from 'typeorm';
|
||||||
import { perUserReactionsChart } from '../../chart';
|
import { perUserReactionsChart } from '../../chart';
|
||||||
import { genId } from '../../../misc/gen-id';
|
import { genId } from '../../../misc/gen-id';
|
||||||
|
@ -79,8 +79,10 @@ export default async (user: User, note: Note, reaction: string) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const profile = await UserProfiles.findOne({ userId: user.id });
|
||||||
|
|
||||||
// ユーザーがローカルユーザーかつ自動ウォッチ設定がオンならばこの投稿をWatchする
|
// ユーザーがローカルユーザーかつ自動ウォッチ設定がオンならばこの投稿をWatchする
|
||||||
if (Users.isLocalUser(user) && user.autoWatch !== false) {
|
if (Users.isLocalUser(user) && profile.autoWatch) {
|
||||||
watch(user.id, note);
|
watch(user.id, note);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue