Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c6cef0162d | ||
![]() |
6d09aa86e9 | ||
![]() |
b711f0f9c6 | ||
![]() |
8fefb3a4c9 | ||
![]() |
400cdf0f26 | ||
![]() |
bce8c5a315 | ||
![]() |
f44dc2dd05 | ||
![]() |
df950d2fc5 | ||
![]() |
5e1f804dd1 | ||
![]() |
15de89f2f9 | ||
![]() |
df647a415c | ||
![]() |
fc66231f8e | ||
![]() |
71df3e1566 | ||
![]() |
168c22fc98 | ||
![]() |
792ec23d7a |
13
CHANGELOG.md
13
CHANGELOG.md
@@ -5,6 +5,19 @@ If you encounter any problems with updating, please try the following:
|
|||||||
1. `npm run clean` or `npm run cleanall`
|
1. `npm run clean` or `npm run cleanall`
|
||||||
2. Retry update (Don't forget `npm i`)
|
2. Retry update (Don't forget `npm i`)
|
||||||
|
|
||||||
|
11.1.3 (2019/04/16)
|
||||||
|
-------------------
|
||||||
|
### Fixes
|
||||||
|
* アプリからAPIにリクエストするときにランダムなユーザーがリクエストしたことになる問題を修正
|
||||||
|
|
||||||
|
11.1.2 (2019/04/15)
|
||||||
|
-------------------
|
||||||
|
### Fixes
|
||||||
|
* 画像描画の依存関係を変更
|
||||||
|
* リモートユーザーのファイルを削除するときに古い方からではなく新しい方から削除されるのを修正
|
||||||
|
* リアクションしてないのにリアクションしたことになる問題を修正
|
||||||
|
* APIドキュメントの修正
|
||||||
|
|
||||||
11.1.1 (2019/04/15)
|
11.1.1 (2019/04/15)
|
||||||
-------------------
|
-------------------
|
||||||
### Fixes
|
### Fixes
|
||||||
|
@@ -57,7 +57,13 @@ Build misskey with the following:
|
|||||||
|
|
||||||
`docker-compose build`
|
`docker-compose build`
|
||||||
|
|
||||||
*5.* That is it.
|
*5.* Init DB
|
||||||
|
----------------------------------------------------------------
|
||||||
|
``` shell
|
||||||
|
docker-compose run --rm web npm run init
|
||||||
|
```
|
||||||
|
|
||||||
|
*6.* That is it.
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
Well done! Now you have an environment to run Misskey.
|
Well done! Now you have an environment to run Misskey.
|
||||||
|
|
||||||
|
@@ -57,7 +57,13 @@ cp docker_example.env docker.env
|
|||||||
|
|
||||||
`docker-compose build`
|
`docker-compose build`
|
||||||
|
|
||||||
*5.* 以上です!
|
*5.* データベースを初期化
|
||||||
|
----------------------------------------------------------------
|
||||||
|
``` shell
|
||||||
|
docker-compose run --rm web npm run init
|
||||||
|
```
|
||||||
|
|
||||||
|
*6.* 以上です!
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
お疲れ様でした。これでMisskeyを動かす準備は整いました。
|
お疲れ様でした。これでMisskeyを動かす準備は整いました。
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"author": "syuilo <i@syuilo.com>",
|
"author": "syuilo <i@syuilo.com>",
|
||||||
"version": "11.1.1",
|
"version": "11.1.3",
|
||||||
"codename": "daybreak",
|
"codename": "daybreak",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -104,7 +104,6 @@
|
|||||||
"bootstrap-vue": "2.0.0-rc.13",
|
"bootstrap-vue": "2.0.0-rc.13",
|
||||||
"bull": "3.7.0",
|
"bull": "3.7.0",
|
||||||
"cafy": "15.1.1",
|
"cafy": "15.1.1",
|
||||||
"canvas": "2.4.1",
|
|
||||||
"chai": "4.2.0",
|
"chai": "4.2.0",
|
||||||
"chalk": "2.4.2",
|
"chalk": "2.4.2",
|
||||||
"cli-highlight": "2.1.0",
|
"cli-highlight": "2.1.0",
|
||||||
@@ -189,6 +188,7 @@
|
|||||||
"promise-sequential": "1.1.1",
|
"promise-sequential": "1.1.1",
|
||||||
"pug": "2.0.3",
|
"pug": "2.0.3",
|
||||||
"punycode": "2.1.1",
|
"punycode": "2.1.1",
|
||||||
|
"pureimage": "0.1.6",
|
||||||
"qrcode": "1.3.3",
|
"qrcode": "1.3.3",
|
||||||
"random-seed": "0.3.0",
|
"random-seed": "0.3.0",
|
||||||
"randomcolor": "0.5.4",
|
"randomcolor": "0.5.4",
|
||||||
|
@@ -2,10 +2,11 @@
|
|||||||
* Random avatar generator
|
* Random avatar generator
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createCanvas } from 'canvas';
|
const p = require('pureimage');
|
||||||
import * as gen from 'random-seed';
|
import * as gen from 'random-seed';
|
||||||
|
import { WriteStream } from 'fs';
|
||||||
|
|
||||||
const size = 512; // px
|
const size = 256; // px
|
||||||
const n = 5; // resolution
|
const n = 5; // resolution
|
||||||
const margin = (size / n) / 1.5;
|
const margin = (size / n) / 1.5;
|
||||||
const colors = [
|
const colors = [
|
||||||
@@ -35,9 +36,9 @@ const sideN = Math.floor(n / 2);
|
|||||||
/**
|
/**
|
||||||
* Generate buffer of random avatar by seed
|
* Generate buffer of random avatar by seed
|
||||||
*/
|
*/
|
||||||
export function genAvatar(seed: string) {
|
export function genAvatar(seed: string, stream: WriteStream): Promise<void> {
|
||||||
const rand = gen.create(seed);
|
const rand = gen.create(seed);
|
||||||
const canvas = createCanvas(size, size);
|
const canvas = p.make(size, size);
|
||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
ctx.fillStyle = bg;
|
ctx.fillStyle = bg;
|
||||||
@@ -85,5 +86,5 @@ export function genAvatar(seed: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return canvas.toBuffer();
|
return p.encodePNGToStream(canvas, stream);
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { Entity, PrimaryColumn, Index, Column, ManyToOne, JoinColumn, RelationId } from 'typeorm';
|
import { Entity, PrimaryColumn, Index, Column, ManyToOne, JoinColumn } from 'typeorm';
|
||||||
import { User } from './user';
|
import { User } from './user';
|
||||||
import { App } from './app';
|
import { App } from './app';
|
||||||
import { id } from '../id';
|
import { id } from '../id';
|
||||||
@@ -25,7 +25,8 @@ export class AccessToken {
|
|||||||
})
|
})
|
||||||
public hash: string;
|
public hash: string;
|
||||||
|
|
||||||
@RelationId((self: AccessToken) => self.user)
|
@Index()
|
||||||
|
@Column(id())
|
||||||
public userId: User['id'];
|
public userId: User['id'];
|
||||||
|
|
||||||
@ManyToOne(type => User, {
|
@ManyToOne(type => User, {
|
||||||
|
@@ -31,7 +31,9 @@ export default async (token: string): Promise<[User | null | undefined, App | nu
|
|||||||
.findOne(accessToken.appId);
|
.findOne(accessToken.appId);
|
||||||
|
|
||||||
const user = await Users
|
const user = await Users
|
||||||
.findOne(accessToken.userId);
|
.findOne({
|
||||||
|
id: accessToken.userId // findOne(accessToken.userId) のように書かないのは後方互換性のため
|
||||||
|
});
|
||||||
|
|
||||||
return [user, app];
|
return [user, app];
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
import rndstr from 'rndstr';
|
import rndstr from 'rndstr';
|
||||||
|
|
||||||
export default () => `0${rndstr('a-zA-Z0-9', 15)}`;
|
export default () => rndstr('a-zA-Z0-9', 16);
|
||||||
|
@@ -1 +1 @@
|
|||||||
export default (token: string) => token.startsWith('0');
|
export default (token: string) => token.length === 16;
|
||||||
|
@@ -10,24 +10,68 @@ export const meta = {
|
|||||||
|
|
||||||
requireCredential: false,
|
requireCredential: false,
|
||||||
|
|
||||||
|
desc: {
|
||||||
|
'ja-JP': 'アプリを作成します。',
|
||||||
|
'en-US': 'Create a application.'
|
||||||
|
},
|
||||||
|
|
||||||
params: {
|
params: {
|
||||||
name: {
|
name: {
|
||||||
validator: $.str
|
validator: $.str,
|
||||||
|
desc: {
|
||||||
|
'ja-JP': 'アプリの名前',
|
||||||
|
'en-US': 'Name of application'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
description: {
|
description: {
|
||||||
validator: $.str
|
validator: $.str,
|
||||||
|
desc: {
|
||||||
|
'ja-JP': 'アプリの説明',
|
||||||
|
'en-US': 'Description of application'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
permission: {
|
permission: {
|
||||||
validator: $.arr($.str).unique()
|
validator: $.arr($.str).unique(),
|
||||||
|
desc: {
|
||||||
|
'ja-JP': 'このアプリに割り当てる権限(権限については"Permissions"を参照)',
|
||||||
|
'en-US': 'Permissions assigned to this app (see "Permissions" for the permissions)'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO: Check it is valid url
|
// TODO: Check it is valid url
|
||||||
callbackUrl: {
|
callbackUrl: {
|
||||||
validator: $.optional.nullable.str,
|
validator: $.optional.nullable.str,
|
||||||
default: null as any
|
default: null as any,
|
||||||
|
desc: {
|
||||||
|
'ja-JP': 'アプリ認証時にコールバックするURL',
|
||||||
|
'en-US': 'URL to call back at app authentication'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
res: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
type: 'string',
|
||||||
|
description: 'アプリケーションのID'
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
description: 'アプリケーションの名前'
|
||||||
|
},
|
||||||
|
callbackUrl: {
|
||||||
|
type: 'string',
|
||||||
|
nullable: true,
|
||||||
|
description: 'コールバックするURL'
|
||||||
|
},
|
||||||
|
secret: {
|
||||||
|
type: 'string',
|
||||||
|
description: 'アプリケーションのシークレットキー'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -39,7 +39,7 @@ export default define(meta, async (ps, user) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate access token
|
// Generate access token
|
||||||
const accessToken = '1' + rndstr('a-zA-Z0-9', 15);
|
const accessToken = rndstr('a-zA-Z0-9', 32);
|
||||||
|
|
||||||
// Fetch exist access token
|
// Fetch exist access token
|
||||||
const exist = await AccessTokens.findOne({
|
const exist = await AccessTokens.findOne({
|
||||||
|
@@ -11,6 +11,11 @@ export const meta = {
|
|||||||
|
|
||||||
requireCredential: false,
|
requireCredential: false,
|
||||||
|
|
||||||
|
desc: {
|
||||||
|
'ja-JP': 'アプリを認証するためのトークンを作成します。',
|
||||||
|
'en-US': 'Generate a token for authorize application.'
|
||||||
|
},
|
||||||
|
|
||||||
params: {
|
params: {
|
||||||
appSecret: {
|
appSecret: {
|
||||||
validator: $.str,
|
validator: $.str,
|
||||||
|
@@ -238,8 +238,6 @@ export default define(meta, async (ps, user, app) => {
|
|||||||
userId: user.id
|
userId: user.id
|
||||||
})
|
})
|
||||||
))).filter(file => file != null) as DriveFile[];
|
))).filter(file => file != null) as DriveFile[];
|
||||||
|
|
||||||
files = files;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let renote: Note | undefined;
|
let renote: Note | undefined;
|
||||||
|
@@ -196,5 +196,5 @@ export default define(meta, async (ps, me) => {
|
|||||||
|
|
||||||
const timeline = await query.take(ps.limit!).getMany();
|
const timeline = await query.take(ps.limit!).getMany();
|
||||||
|
|
||||||
return await Notes.packMany(timeline, user);
|
return await Notes.packMany(timeline, me);
|
||||||
});
|
});
|
||||||
|
@@ -26,6 +26,7 @@ import { program } from '../argv';
|
|||||||
import { UserProfiles } from '../models';
|
import { UserProfiles } from '../models';
|
||||||
import { networkChart } from '../services/chart';
|
import { networkChart } from '../services/chart';
|
||||||
import { genAvatar } from '../misc/gen-avatar';
|
import { genAvatar } from '../misc/gen-avatar';
|
||||||
|
import { createTemp } from '../misc/create-temp';
|
||||||
|
|
||||||
export const serverLogger = new Logger('server', 'gray', false);
|
export const serverLogger = new Logger('server', 'gray', false);
|
||||||
|
|
||||||
@@ -73,10 +74,11 @@ router.use(activityPub.routes());
|
|||||||
router.use(nodeinfo.routes());
|
router.use(nodeinfo.routes());
|
||||||
router.use(wellKnown.routes());
|
router.use(wellKnown.routes());
|
||||||
|
|
||||||
router.get('/avatar/:x', ctx => {
|
router.get('/avatar/:x', async ctx => {
|
||||||
const avatar = genAvatar(ctx.params.x);
|
const [temp] = await createTemp();
|
||||||
|
await genAvatar(ctx.params.x, fs.createWriteStream(temp));
|
||||||
ctx.set('Content-Type', 'image/png');
|
ctx.set('Content-Type', 'image/png');
|
||||||
ctx.body = avatar;
|
ctx.body = fs.createReadStream(temp);
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/verify-email/:code', async ctx => {
|
router.get('/verify-email/:code', async ctx => {
|
||||||
|
@@ -212,7 +212,7 @@ async function deleteOldFile(user: IRemoteUser) {
|
|||||||
q.andWhere('file.id != :bannerId', { bannerId: user.bannerId });
|
q.andWhere('file.id != :bannerId', { bannerId: user.bannerId });
|
||||||
}
|
}
|
||||||
|
|
||||||
q.orderBy('file.id', 'DESC');
|
q.orderBy('file.id', 'ASC');
|
||||||
|
|
||||||
const oldFile = await q.getOne();
|
const oldFile = await q.getOne();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user