mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-11-23 09:33:09 +02:00
Merge branch 'master' of https://github.com/syuilo/misskey
This commit is contained in:
commit
27183b2142
16 changed files with 325 additions and 1 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
||||||
/.config
|
/.config
|
||||||
/.vscode
|
/.vscode
|
||||||
/node_modules
|
/node_modules
|
||||||
|
/build
|
||||||
/built
|
/built
|
||||||
/data
|
/data
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
|
|
9
binding.gyp
Normal file
9
binding.gyp
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
'targets': [
|
||||||
|
{
|
||||||
|
'target_name': 'crypto_key',
|
||||||
|
'sources': ['src/crypto_key.cc'],
|
||||||
|
'include_dirs': ['<!(node -e "require(\'nan\')")']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -69,6 +69,7 @@ gulp.task('build:ts', () => {
|
||||||
|
|
||||||
gulp.task('build:copy', () =>
|
gulp.task('build:copy', () =>
|
||||||
gulp.src([
|
gulp.src([
|
||||||
|
'./build/Release/crypto_key.node',
|
||||||
'./src/**/assets/**/*',
|
'./src/**/assets/**/*',
|
||||||
'!./src/web/app/**/assets/**/*'
|
'!./src/web/app/**/assets/**/*'
|
||||||
]).pipe(gulp.dest('./built/'))
|
]).pipe(gulp.dest('./built/'))
|
||||||
|
|
|
@ -145,6 +145,7 @@
|
||||||
"morgan": "1.9.0",
|
"morgan": "1.9.0",
|
||||||
"ms": "2.1.1",
|
"ms": "2.1.1",
|
||||||
"multer": "1.3.0",
|
"multer": "1.3.0",
|
||||||
|
"nan": "^2.10.0",
|
||||||
"node-sass": "4.7.2",
|
"node-sass": "4.7.2",
|
||||||
"node-sass-json-importer": "3.1.5",
|
"node-sass-json-importer": "3.1.5",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
|
|
|
@ -59,6 +59,7 @@ export type IUser = {
|
||||||
is_suspended: boolean;
|
is_suspended: boolean;
|
||||||
keywords: string[];
|
keywords: string[];
|
||||||
account: {
|
account: {
|
||||||
|
keypair: string;
|
||||||
email: string;
|
email: string;
|
||||||
links: string[];
|
links: string[];
|
||||||
password: string;
|
password: string;
|
||||||
|
@ -160,6 +161,7 @@ export const pack = (
|
||||||
delete _user.latest_post;
|
delete _user.latest_post;
|
||||||
|
|
||||||
// Remove private properties
|
// Remove private properties
|
||||||
|
delete _user.account.keypair;
|
||||||
delete _user.account.password;
|
delete _user.account.password;
|
||||||
delete _user.account.token;
|
delete _user.account.token;
|
||||||
delete _user.account.two_factor_temp_secret;
|
delete _user.account.two_factor_temp_secret;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import * as uuid from 'uuid';
|
import * as uuid from 'uuid';
|
||||||
import * as express from 'express';
|
import * as express from 'express';
|
||||||
import * as bcrypt from 'bcryptjs';
|
import * as bcrypt from 'bcryptjs';
|
||||||
|
import { generate as generateKeypair } from '../../crypto_key';
|
||||||
import recaptcha = require('recaptcha-promise');
|
import recaptcha = require('recaptcha-promise');
|
||||||
import User, { IUser, validateUsername, validatePassword, pack } from '../models/user';
|
import User, { IUser, validateUsername, validatePassword, pack } from '../models/user';
|
||||||
import generateUserToken from '../common/generate-native-user-token';
|
import generateUserToken from '../common/generate-native-user-token';
|
||||||
|
@ -119,6 +120,7 @@ export default async (req: express.Request, res: express.Response) => {
|
||||||
username: username,
|
username: username,
|
||||||
username_lower: username.toLowerCase(),
|
username_lower: username.toLowerCase(),
|
||||||
account: {
|
account: {
|
||||||
|
keypair: generateKeypair(),
|
||||||
token: secret,
|
token: secret,
|
||||||
email: null,
|
email: null,
|
||||||
links: null,
|
links: null,
|
||||||
|
|
111
src/crypto_key.cc
Normal file
111
src/crypto_key.cc
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
#include <nan.h>
|
||||||
|
#include <openssl/bio.h>
|
||||||
|
#include <openssl/buffer.h>
|
||||||
|
#include <openssl/crypto.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
|
||||||
|
NAN_METHOD(extractPublic)
|
||||||
|
{
|
||||||
|
const auto sourceString = info[0]->ToString();
|
||||||
|
if (!sourceString->IsOneByte()) {
|
||||||
|
Nan::ThrowError("Malformed character found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t sourceLength = sourceString->Length();
|
||||||
|
const auto sourceBuf = new char[sourceLength];
|
||||||
|
|
||||||
|
Nan::DecodeWrite(sourceBuf, sourceLength, sourceString);
|
||||||
|
|
||||||
|
const auto source = BIO_new_mem_buf(sourceBuf, sourceLength);
|
||||||
|
if (source == nullptr) {
|
||||||
|
Nan::ThrowError("Memory allocation failed");
|
||||||
|
delete sourceBuf;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto rsa = PEM_read_bio_RSAPrivateKey(source, nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
|
BIO_free(source);
|
||||||
|
delete sourceBuf;
|
||||||
|
|
||||||
|
if (rsa == nullptr) {
|
||||||
|
Nan::ThrowError("Decode failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto destination = BIO_new(BIO_s_mem());
|
||||||
|
if (destination == nullptr) {
|
||||||
|
Nan::ThrowError("Memory allocation failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto result = PEM_write_bio_RSAPublicKey(destination, rsa);
|
||||||
|
|
||||||
|
RSA_free(rsa);
|
||||||
|
|
||||||
|
if (result != 1) {
|
||||||
|
Nan::ThrowError("Public key extraction failed");
|
||||||
|
BIO_free(destination);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *pem;
|
||||||
|
const auto pemLength = BIO_get_mem_data(destination, &pem);
|
||||||
|
|
||||||
|
info.GetReturnValue().Set(Nan::Encode(pem, pemLength));
|
||||||
|
BIO_free(destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
NAN_METHOD(generate)
|
||||||
|
{
|
||||||
|
const auto exponent = BN_new();
|
||||||
|
const auto mem = BIO_new(BIO_s_mem());
|
||||||
|
const auto rsa = RSA_new();
|
||||||
|
char *data;
|
||||||
|
long result;
|
||||||
|
|
||||||
|
if (exponent == nullptr || mem == nullptr || rsa == nullptr) {
|
||||||
|
Nan::ThrowError("Memory allocation failed");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = BN_set_word(exponent, 65537);
|
||||||
|
if (result != 1) {
|
||||||
|
Nan::ThrowError("Exponent setting failed");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = RSA_generate_key_ex(rsa, 2048, exponent, nullptr);
|
||||||
|
if (result != 1) {
|
||||||
|
Nan::ThrowError("Key generation failed");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = PEM_write_bio_RSAPrivateKey(mem, rsa, NULL, NULL, 0, NULL, NULL);
|
||||||
|
if (result != 1) {
|
||||||
|
Nan::ThrowError("Key export failed");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = BIO_get_mem_data(mem, &data);
|
||||||
|
info.GetReturnValue().Set(Nan::Encode(data, result));
|
||||||
|
|
||||||
|
done:
|
||||||
|
RSA_free(rsa);
|
||||||
|
BIO_free(mem);
|
||||||
|
BN_free(exponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
NAN_MODULE_INIT(InitAll)
|
||||||
|
{
|
||||||
|
Nan::Set(target, Nan::New<v8::String>("extractPublic").ToLocalChecked(),
|
||||||
|
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(extractPublic)).ToLocalChecked());
|
||||||
|
|
||||||
|
Nan::Set(target, Nan::New<v8::String>("generate").ToLocalChecked(),
|
||||||
|
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(generate)).ToLocalChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
NODE_MODULE(crypto_key, InitAll);
|
1
src/crypto_key.d.ts
vendored
Normal file
1
src/crypto_key.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export function generate(): String;
|
|
@ -1,7 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-media-list" :data-count="mediaList.length">
|
<div class="mk-media-list" :data-count="mediaList.length">
|
||||||
<template v-for="media in mediaList">
|
<template v-for="media in mediaList">
|
||||||
<mk-media-image :image="media" :key="media.id"/>
|
<mk-media-video :video="media" :key="media.id" v-if="media.type.startsWith('video')" :inline-playable="mediaList.length === 1"/>
|
||||||
|
<mk-media-image :image="media" :key="media.id" v-else />
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -13,6 +13,7 @@ import analogClock from './analog-clock.vue';
|
||||||
import ellipsisIcon from './ellipsis-icon.vue';
|
import ellipsisIcon from './ellipsis-icon.vue';
|
||||||
import mediaImage from './media-image.vue';
|
import mediaImage from './media-image.vue';
|
||||||
import mediaImageDialog from './media-image-dialog.vue';
|
import mediaImageDialog from './media-image-dialog.vue';
|
||||||
|
import mediaVideo from './media-video.vue';
|
||||||
import notifications from './notifications.vue';
|
import notifications from './notifications.vue';
|
||||||
import postForm from './post-form.vue';
|
import postForm from './post-form.vue';
|
||||||
import repostForm from './repost-form.vue';
|
import repostForm from './repost-form.vue';
|
||||||
|
@ -42,6 +43,7 @@ Vue.component('mk-analog-clock', analogClock);
|
||||||
Vue.component('mk-ellipsis-icon', ellipsisIcon);
|
Vue.component('mk-ellipsis-icon', ellipsisIcon);
|
||||||
Vue.component('mk-media-image', mediaImage);
|
Vue.component('mk-media-image', mediaImage);
|
||||||
Vue.component('mk-media-image-dialog', mediaImageDialog);
|
Vue.component('mk-media-image-dialog', mediaImageDialog);
|
||||||
|
Vue.component('mk-media-video', mediaVideo);
|
||||||
Vue.component('mk-notifications', notifications);
|
Vue.component('mk-notifications', notifications);
|
||||||
Vue.component('mk-post-form', postForm);
|
Vue.component('mk-post-form', postForm);
|
||||||
Vue.component('mk-repost-form', repostForm);
|
Vue.component('mk-repost-form', repostForm);
|
||||||
|
|
70
src/web/app/desktop/views/components/media-video-dialog.vue
Normal file
70
src/web/app/desktop/views/components/media-video-dialog.vue
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
<template>
|
||||||
|
<div class="mk-media-video-dialog">
|
||||||
|
<div class="bg" @click="close"></div>
|
||||||
|
<video :src="video.url" :title="video.name" controls autoplay ref="video"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import * as anime from 'animejs';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
props: ['video', 'start'],
|
||||||
|
mounted() {
|
||||||
|
anime({
|
||||||
|
targets: this.$el,
|
||||||
|
opacity: 1,
|
||||||
|
duration: 100,
|
||||||
|
easing: 'linear'
|
||||||
|
});
|
||||||
|
const videoTag = this.$refs.video as HTMLVideoElement
|
||||||
|
if (this.start) videoTag.currentTime = this.start
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
close() {
|
||||||
|
anime({
|
||||||
|
targets: this.$el,
|
||||||
|
opacity: 0,
|
||||||
|
duration: 100,
|
||||||
|
easing: 'linear',
|
||||||
|
complete: () => this.$destroy()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.mk-media-video-dialog
|
||||||
|
display block
|
||||||
|
position fixed
|
||||||
|
z-index 2048
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
opacity 0
|
||||||
|
|
||||||
|
> .bg
|
||||||
|
display block
|
||||||
|
position fixed
|
||||||
|
z-index 1
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
background rgba(0, 0, 0, 0.7)
|
||||||
|
|
||||||
|
> video
|
||||||
|
position fixed
|
||||||
|
z-index 2
|
||||||
|
top 0
|
||||||
|
right 0
|
||||||
|
bottom 0
|
||||||
|
left 0
|
||||||
|
max-width 80vw
|
||||||
|
max-height 80vh
|
||||||
|
margin auto
|
||||||
|
|
||||||
|
</style>
|
67
src/web/app/desktop/views/components/media-video.vue
Normal file
67
src/web/app/desktop/views/components/media-video.vue
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
<template>
|
||||||
|
<video class="mk-media-video"
|
||||||
|
:src="video.url"
|
||||||
|
:title="video.name"
|
||||||
|
controls
|
||||||
|
@dblclick.prevent="onClick"
|
||||||
|
ref="video"
|
||||||
|
v-if="inlinePlayable" />
|
||||||
|
<a class="mk-media-video-thumbnail"
|
||||||
|
:href="video.url"
|
||||||
|
:style="imageStyle"
|
||||||
|
@click.prevent="onClick"
|
||||||
|
:title="video.name"
|
||||||
|
v-else>
|
||||||
|
%fa:R play-circle%
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import MkMediaVideoDialog from './media-video-dialog.vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
props: ['video', 'inlinePlayable'],
|
||||||
|
computed: {
|
||||||
|
imageStyle(): any {
|
||||||
|
return {
|
||||||
|
'background-image': `url(${this.video.url}?thumbnail&size=512)`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onClick() {
|
||||||
|
const videoTag = this.$refs.video as (HTMLVideoElement | null)
|
||||||
|
var start = 0
|
||||||
|
if (videoTag) {
|
||||||
|
start = videoTag.currentTime
|
||||||
|
videoTag.pause()
|
||||||
|
}
|
||||||
|
(this as any).os.new(MkMediaVideoDialog, {
|
||||||
|
video: this.video,
|
||||||
|
start,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.mk-media-video
|
||||||
|
display block
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
border-radius 4px
|
||||||
|
.mk-media-video-thumbnail
|
||||||
|
display flex
|
||||||
|
justify-content center
|
||||||
|
align-items center
|
||||||
|
font-size 3.5em
|
||||||
|
|
||||||
|
cursor zoom-in
|
||||||
|
overflow hidden
|
||||||
|
background-position center
|
||||||
|
background-size cover
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
</style>
|
|
@ -5,6 +5,7 @@ import timeline from './timeline.vue';
|
||||||
import post from './post.vue';
|
import post from './post.vue';
|
||||||
import posts from './posts.vue';
|
import posts from './posts.vue';
|
||||||
import mediaImage from './media-image.vue';
|
import mediaImage from './media-image.vue';
|
||||||
|
import mediaVideo from './media-video.vue';
|
||||||
import drive from './drive.vue';
|
import drive from './drive.vue';
|
||||||
import postPreview from './post-preview.vue';
|
import postPreview from './post-preview.vue';
|
||||||
import subPostContent from './sub-post-content.vue';
|
import subPostContent from './sub-post-content.vue';
|
||||||
|
@ -27,6 +28,7 @@ Vue.component('mk-timeline', timeline);
|
||||||
Vue.component('mk-post', post);
|
Vue.component('mk-post', post);
|
||||||
Vue.component('mk-posts', posts);
|
Vue.component('mk-posts', posts);
|
||||||
Vue.component('mk-media-image', mediaImage);
|
Vue.component('mk-media-image', mediaImage);
|
||||||
|
Vue.component('mk-media-video', mediaVideo);
|
||||||
Vue.component('mk-drive', drive);
|
Vue.component('mk-drive', drive);
|
||||||
Vue.component('mk-post-preview', postPreview);
|
Vue.component('mk-post-preview', postPreview);
|
||||||
Vue.component('mk-sub-post-content', subPostContent);
|
Vue.component('mk-sub-post-content', subPostContent);
|
||||||
|
|
36
src/web/app/mobile/views/components/media-video.vue
Normal file
36
src/web/app/mobile/views/components/media-video.vue
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<template>
|
||||||
|
<a class="mk-media-video"
|
||||||
|
:href="video.url"
|
||||||
|
target="_blank"
|
||||||
|
:style="imageStyle"
|
||||||
|
:title="video.name">
|
||||||
|
%fa:R play-circle%
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue'
|
||||||
|
export default Vue.extend({
|
||||||
|
props: ['video'],
|
||||||
|
computed: {
|
||||||
|
imageStyle(): any {
|
||||||
|
return {
|
||||||
|
'background-image': `url(${this.video.url}?thumbnail&size=512)`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.mk-media-video
|
||||||
|
display flex
|
||||||
|
justify-content center
|
||||||
|
align-items center
|
||||||
|
|
||||||
|
font-size 3.5em
|
||||||
|
overflow hidden
|
||||||
|
background-position center
|
||||||
|
background-size cover
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
</style>
|
|
@ -1161,6 +1161,7 @@ function insertSakurako(opts) {
|
||||||
username: 'sakurako',
|
username: 'sakurako',
|
||||||
username_lower: 'sakurako',
|
username_lower: 'sakurako',
|
||||||
account: {
|
account: {
|
||||||
|
keypair: '-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAtdTG9rlFWjNqhgbg2V6X5XF1WpQXZS3KNXykEWl2UAiMyfVV\nBvf3zQP0dDEdNtcqdPJgis03bpiHCzQusc/YLyHYB0m+TJXsxJatb8cqUogOFeE4\ngQ4Dc5kAT6gLh/d4yz03EIg9bizX07EiGWnZqWxb+21ypqsPxST64sAtG9f5O/G4\nXe2m3cSbfAAvEUP1Ig1LUNyJB4jhM60w1cQic/qO8++sk/+GoX9g71X+i4NArGv+\n1c11acDIIPGAAQpFeYVeGaKakNDNp8RtJJp8R8FLwJXZ4/gATBnScCiHUSrGfRly\nYyR0w/BNlQ6/NijAdB9pR5csPvyIPkx1gauZewIDAQABAoIBAQCwWf/mhuY2h6uG\n9eDZsZ7Mj2/sO7k9Dl4R5iMSKCDxmnlB3slqitExa+aJUqEs8R5icjkkJcjfYNuJ\nCEFJf3YCsGZfGyyQBtCuEh2ATcBEb2SJ3/f3YuoCEaB1oVwdsOzc4TAovpol4yQo\nUqHp1/mdElVb01jhQQN4h1c02IJnfzvfU1C8szBni+Etfd+MxqGfv006DY3KOEb3\nlCrCS3GmooJW2Fjj7q1kCcaEQbMB1/aQHLXd1qe3KJOzXh3Voxsp/jEH0hvp2TII\nfY9UK+b7mA+xlvXwKuTkHVaZm0ylg0nbembS8MF4GfFMujinSexvLrVKaQhdMFoF\nvBLxHYHRAoGBANfNVYJYeCDPFNLmak5Xg33Rfvc2II8UmrZOVdhOWs8ZK0pis9e+\nPo2MKtTzrzipXI2QXv5w7kO+LJWNDva+xRlW8Wlj9Dde9QdQ7Y8+dk7SJgf24DzM\n023elgX5DvTeLODjStk6SMPRL0FmGovUqAAA8ZeHtJzkIr1HROWnQiwnAoGBANez\nhFwKnVoQu0RpBz/i4W0RKIxOwltN2zmlN8KjJPhSy00A7nBUfKLRbcwiSHE98Yi/\nUrXwMwR5QeD2ngngRppddJnpiRfjNjnsaqeqNtpO8AxB3XjpCC5zmHUMFHKvPpDj\n1zU/F44li0YjKcMBebZy9PbfAjrIgJfxhPo/oXiNAoGAfx6gaTjOAp2ZaaZ7Jozc\nkyft/5et1DrR6+P3I4T8bxQncRj1UXfqhxzzOiAVrm3tbCKIIp/JarRCtRGzp9u2\nZPfXGzra6CcSdW3Rkli7/jBCYNynOIl7XjQI8ZnFmq6phwu80ntH07mMeZy4tHff\nQqlLpvQ0i1rDr/Wkexdsnm8CgYBgxha9ILoF/Xm3MJPjEsxmnYsen/tM8XpIu5pv\nxbhBfQvfKWrQlOcyOVnUexEbVVo3KvdVz0VkXW60GpE/BxNGEGXO49rxD6x1gl87\nh/+CJGZIaYiOxaY5CP2+jcPizEL6yG32Yq8TxD5fIkmLRu8vbxX+aIFclDY1dVNe\n3wt3xQKBgGEL0EjwRch+P2V+YHAhbETPrEqJjHRWT95pIdF9XtC8fasSOVH81cLX\nXXsX1FTvOJNwG9Nk8rQjYJXGTb2O/2unaazlYUwxKwVpwuGzz/vhH/roHZBAkIVT\njvpykpn9QMezEdpzj5BEv01QzSYBPzIh5myrpoJIoSW7py7zFG3h\n-----END RSA PRIVATE KEY-----\n',
|
||||||
token: '!00000000000000000000000000000000',
|
token: '!00000000000000000000000000000000',
|
||||||
password: '$2a$08$FnHXg3tP.M/kINWgQSXNqeoBsiVrkj.ecXX8mW9rfBzMRkibYfjYy', // HimawariDaisuki06160907
|
password: '$2a$08$FnHXg3tP.M/kINWgQSXNqeoBsiVrkj.ecXX8mW9rfBzMRkibYfjYy', // HimawariDaisuki06160907
|
||||||
profile: {},
|
profile: {},
|
||||||
|
@ -1175,6 +1176,7 @@ function insertHimawari(opts) {
|
||||||
username: 'himawari',
|
username: 'himawari',
|
||||||
username_lower: 'himawari',
|
username_lower: 'himawari',
|
||||||
account: {
|
account: {
|
||||||
|
keypair: '-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAtdTG9rlFWjNqhgbg2V6X5XF1WpQXZS3KNXykEWl2UAiMyfVV\nBvf3zQP0dDEdNtcqdPJgis03bpiHCzQusc/YLyHYB0m+TJXsxJatb8cqUogOFeE4\ngQ4Dc5kAT6gLh/d4yz03EIg9bizX07EiGWnZqWxb+21ypqsPxST64sAtG9f5O/G4\nXe2m3cSbfAAvEUP1Ig1LUNyJB4jhM60w1cQic/qO8++sk/+GoX9g71X+i4NArGv+\n1c11acDIIPGAAQpFeYVeGaKakNDNp8RtJJp8R8FLwJXZ4/gATBnScCiHUSrGfRly\nYyR0w/BNlQ6/NijAdB9pR5csPvyIPkx1gauZewIDAQABAoIBAQCwWf/mhuY2h6uG\n9eDZsZ7Mj2/sO7k9Dl4R5iMSKCDxmnlB3slqitExa+aJUqEs8R5icjkkJcjfYNuJ\nCEFJf3YCsGZfGyyQBtCuEh2ATcBEb2SJ3/f3YuoCEaB1oVwdsOzc4TAovpol4yQo\nUqHp1/mdElVb01jhQQN4h1c02IJnfzvfU1C8szBni+Etfd+MxqGfv006DY3KOEb3\nlCrCS3GmooJW2Fjj7q1kCcaEQbMB1/aQHLXd1qe3KJOzXh3Voxsp/jEH0hvp2TII\nfY9UK+b7mA+xlvXwKuTkHVaZm0ylg0nbembS8MF4GfFMujinSexvLrVKaQhdMFoF\nvBLxHYHRAoGBANfNVYJYeCDPFNLmak5Xg33Rfvc2II8UmrZOVdhOWs8ZK0pis9e+\nPo2MKtTzrzipXI2QXv5w7kO+LJWNDva+xRlW8Wlj9Dde9QdQ7Y8+dk7SJgf24DzM\n023elgX5DvTeLODjStk6SMPRL0FmGovUqAAA8ZeHtJzkIr1HROWnQiwnAoGBANez\nhFwKnVoQu0RpBz/i4W0RKIxOwltN2zmlN8KjJPhSy00A7nBUfKLRbcwiSHE98Yi/\nUrXwMwR5QeD2ngngRppddJnpiRfjNjnsaqeqNtpO8AxB3XjpCC5zmHUMFHKvPpDj\n1zU/F44li0YjKcMBebZy9PbfAjrIgJfxhPo/oXiNAoGAfx6gaTjOAp2ZaaZ7Jozc\nkyft/5et1DrR6+P3I4T8bxQncRj1UXfqhxzzOiAVrm3tbCKIIp/JarRCtRGzp9u2\nZPfXGzra6CcSdW3Rkli7/jBCYNynOIl7XjQI8ZnFmq6phwu80ntH07mMeZy4tHff\nQqlLpvQ0i1rDr/Wkexdsnm8CgYBgxha9ILoF/Xm3MJPjEsxmnYsen/tM8XpIu5pv\nxbhBfQvfKWrQlOcyOVnUexEbVVo3KvdVz0VkXW60GpE/BxNGEGXO49rxD6x1gl87\nh/+CJGZIaYiOxaY5CP2+jcPizEL6yG32Yq8TxD5fIkmLRu8vbxX+aIFclDY1dVNe\n3wt3xQKBgGEL0EjwRch+P2V+YHAhbETPrEqJjHRWT95pIdF9XtC8fasSOVH81cLX\nXXsX1FTvOJNwG9Nk8rQjYJXGTb2O/2unaazlYUwxKwVpwuGzz/vhH/roHZBAkIVT\njvpykpn9QMezEdpzj5BEv01QzSYBPzIh5myrpoJIoSW7py7zFG3h\n-----END RSA PRIVATE KEY-----\n',
|
||||||
token: '!00000000000000000000000000000001',
|
token: '!00000000000000000000000000000001',
|
||||||
password: '$2a$08$OPESxR2RE/ZijjGanNKk6ezSqGFitqsbZqTjWUZPLhORMKxHCbc4O', // ilovesakurako
|
password: '$2a$08$OPESxR2RE/ZijjGanNKk6ezSqGFitqsbZqTjWUZPLhORMKxHCbc4O', // ilovesakurako
|
||||||
profile: {},
|
profile: {},
|
||||||
|
|
16
tools/migration/node.1522066477.user-account-keypair.js
Normal file
16
tools/migration/node.1522066477.user-account-keypair.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
const { default: User } = require('../../built/api/models/user');
|
||||||
|
const { generate } = require('../../built/crypto_key');
|
||||||
|
|
||||||
|
const updates = [];
|
||||||
|
|
||||||
|
User.find({}).each(function(user) {
|
||||||
|
updates.push(User.update({ _id: user._id }, {
|
||||||
|
$set: {
|
||||||
|
account: {
|
||||||
|
keypair: generate(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}).then(function () {
|
||||||
|
Promise.all(updates)
|
||||||
|
}).then(process.exit);
|
Loading…
Reference in a new issue