Needs to be done: copy link and setup window
This commit is contained in:
parent
b04208106f
commit
546943d762
@ -1,6 +1,8 @@
|
||||
const mongoose = require("mongoose");
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const crypto = require("crypto");
|
||||
|
||||
const CampaignSchema = new Schema({
|
||||
name: {type: String, required: true},
|
||||
description: {type: String},
|
||||
@ -12,14 +14,7 @@ const CampaignSchema = new Schema({
|
||||
});
|
||||
|
||||
CampaignSchema.statics.generateInvite = function() {
|
||||
let possible = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTVWXYZ0123456789";
|
||||
let cod = '';
|
||||
|
||||
for (let i = 0; i < 32; i++) {
|
||||
cod += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
|
||||
return cod;
|
||||
return crypto.randomBytes(8).toString('base64url');
|
||||
}
|
||||
|
||||
module.exports = mongoose.model('Campaign', CampaignSchema);
|
@ -9,6 +9,7 @@ const UserSchema = new Schema({
|
||||
date: { type: Date, default: Date.now},
|
||||
admin: {type: Boolean, default: false},
|
||||
image: { type: String },
|
||||
setupCode: { type: String },
|
||||
settings: { type: Object }
|
||||
});
|
||||
|
||||
|
@ -11,21 +11,6 @@ const User = require("../models/User");
|
||||
router.post('/register', rateLimitMiddleware, (req, res) => {
|
||||
User.findOne({admin: true}).then((data) => {
|
||||
if(!data) {
|
||||
let {
|
||||
name,
|
||||
username,
|
||||
email,
|
||||
password
|
||||
} = req.body;
|
||||
|
||||
if(!(name && username && email && password)){
|
||||
res.json({
|
||||
error: true,
|
||||
msg: "params"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
User.findOne({username: username}).then((user) => {
|
||||
if(user){
|
||||
res.json({
|
||||
|
@ -7,6 +7,7 @@ const passport = require('passport');
|
||||
const secret = require('../config/keys').secret;
|
||||
const rateLimitMiddleware = require("../config/rate-limiter");
|
||||
const { default: jwtDecode } = require('jwt-decode');
|
||||
const crypto = require("crypto");
|
||||
|
||||
const { isAdmin } = require('../config/middleware');
|
||||
|
||||
@ -14,14 +15,47 @@ const User = require("../models/User");
|
||||
|
||||
const upload = require("../config/storage");
|
||||
|
||||
// Admin registers new user
|
||||
router.post('/register', isAdmin, (req, res) => {
|
||||
let setupCode = crypto.randomBytes(64).toString('base64url');
|
||||
|
||||
let user = new User({
|
||||
admin: false,
|
||||
name: crypto.randomBytes(16).toString('base64url'),
|
||||
username: crypto.randomBytes(16).toString('base64url'),
|
||||
email: crypto.randomBytes(16).toString('base64url'),
|
||||
setupCode
|
||||
});
|
||||
|
||||
user.save().then(user => {
|
||||
res.json({
|
||||
status: "ok",
|
||||
code: setupCode,
|
||||
});
|
||||
}).catch({status: "err", msg: "internal"})
|
||||
});
|
||||
|
||||
// User gets if setup account exists given the query code
|
||||
router.get('/setup', (req, res) => {
|
||||
User.findOne({setupCode: req.query.code}).then(user => {
|
||||
if(user){
|
||||
res.json({status: "ok", code: req.query.code});
|
||||
}
|
||||
res.json({status: "err", msg: "not-exists"});
|
||||
}).catch(res.json({status: "err", msg: "internal"}));
|
||||
});
|
||||
|
||||
// User posts the parameters of his new account given by admin
|
||||
router.post('/setup', rateLimitMiddleware, (req, res) => {
|
||||
let {
|
||||
name,
|
||||
username,
|
||||
email
|
||||
email,
|
||||
password
|
||||
} = req.body;
|
||||
let setupCode = req.query.code;
|
||||
|
||||
if(!(name && username && email)){
|
||||
if(!(name && username && email && password && setupCode)){
|
||||
res.json({
|
||||
error: true,
|
||||
msg: "params"
|
||||
@ -29,39 +63,36 @@ router.post('/register', isAdmin, (req, res) => {
|
||||
return;
|
||||
}
|
||||
|
||||
User.findOne({username: username}).then((user) => {
|
||||
if(user){
|
||||
res.json({
|
||||
error: true,
|
||||
msg: "already-exists"
|
||||
});
|
||||
} else {
|
||||
User.findOne({email: email}).then((user) => {
|
||||
if(user){
|
||||
User.findOne({setupCode}).then((user) => {
|
||||
User.findOne({email: email}).then((sameUser) => {
|
||||
if(sameUser){
|
||||
res.json({
|
||||
error: true,
|
||||
msg: "already-email"
|
||||
});
|
||||
} else {
|
||||
var user = new User({
|
||||
name: name,
|
||||
username: username,
|
||||
email: email,
|
||||
admin: true
|
||||
});
|
||||
bcrypt.genSalt(10, (err, salt) => {
|
||||
bcrypt.hash(user.password, salt, (err, hash) => {
|
||||
if(err) throw err;
|
||||
user.password = hash;
|
||||
user.username = username;
|
||||
user.email = email;
|
||||
user.setupCode = undefined;
|
||||
|
||||
user.save().then(user => {
|
||||
res.json({
|
||||
status: "ok",
|
||||
user
|
||||
success: true
|
||||
});
|
||||
return;
|
||||
}).catch((error) => { res.json({ error: true }); return; });
|
||||
});
|
||||
})
|
||||
}
|
||||
}).catch((error) => { res.json({ error: true, msg: "Hi ha hagut un error intern, prova-ho més tard" }); return; });
|
||||
}
|
||||
}).catch((error) => { res.json({ error: true, msg: "Hi ha hagut un error intern, prova-ho més tard" }); return; });
|
||||
}).catch((error) => { res.json({ error: true, msg: "internal" }); return; });
|
||||
}).catch((error) => { res.json({ error: true, msg: "internal" }); return; });
|
||||
});
|
||||
|
||||
// Login post
|
||||
router.post('/login', rateLimitMiddleware, (req, res) => {
|
||||
const username = req.body.username;
|
||||
const password = req.body.password;
|
||||
@ -111,6 +142,7 @@ router.post('/login', rateLimitMiddleware, (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
// Upload avatar post
|
||||
router.post("/upload-avatar", upload.single("image"), passport.authenticate('jwt', {session: false}), (req, res) => {
|
||||
const imageName = req.file.filename;
|
||||
|
||||
|
@ -31,6 +31,7 @@ import PluginManagementWindow from '@/views/windows/settings/PluginManagementWin
|
||||
import PluginWindow from '../views/windows/settings/PluginWindow.vue';
|
||||
import FirstRegisterWindow from '../views/windows/FirstRegisterWindow.vue';
|
||||
import RegisterUserWindow from '../views/windows/settings/RegisterUserWindow.vue';
|
||||
import CopyPendingUserWindow from '../views/windows/settings/CopyPendingUserWindow.vue';
|
||||
|
||||
let windowMap = {
|
||||
test: ExampleWindow,
|
||||
@ -39,6 +40,7 @@ let windowMap = {
|
||||
welcome: WelcomeWindow,
|
||||
first_register: FirstRegisterWindow,
|
||||
register_user: RegisterUserWindow,
|
||||
copy_pending_user_window: CopyPendingUserWindow,
|
||||
edit_profile: EditProfileWindow,
|
||||
settings: SettingsWindow,
|
||||
campaign_list: CampaignListWindow,
|
||||
|
@ -8,12 +8,14 @@ import Api from '@/services/Api'
|
||||
import BigIconTemplate from '../partials/BigIconTemplate.vue';
|
||||
import { SetMinSize, SetResizable } from '../../services/Windows';
|
||||
import { backendUrl } from '../../services/BackendURL';
|
||||
import { GetUser } from '../../services/User';
|
||||
|
||||
const props = defineProps(['data']);
|
||||
const data = props.data;
|
||||
const userIcon = ref("");
|
||||
|
||||
const handle = ref(null);
|
||||
const isAdmin = ref(false);
|
||||
|
||||
let id = data.id;
|
||||
console.log(data);
|
||||
@ -26,6 +28,8 @@ onMounted(() => {
|
||||
SetResizable(id, true);
|
||||
SetMinSize(id, {width: 350, height: 280});
|
||||
|
||||
isAdmin.value = GetUser().admin;
|
||||
|
||||
Api().get('/user/retrieve-avatar?username=' + data.user.username).then((response) => {
|
||||
if(response.data.image) userIcon.value = backendUrl + "public/" + response.data.image;
|
||||
else userIcon.value = "public/img/def-avatar.jpg";
|
||||
@ -39,7 +43,9 @@ onMounted(() => {
|
||||
<WindowHandle :window="id" ref="handle"></WindowHandle>
|
||||
|
||||
<BigIconTemplate :title="data.user.username" :img="userIcon">
|
||||
|
||||
<div v-show="isAdmin">
|
||||
Admin
|
||||
</div>
|
||||
</BigIconTemplate>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -1,4 +1,8 @@
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
const { t } = useI18n()
|
||||
|
||||
|
||||
import { onMounted, ref, shallowRef, toRaw } from 'vue';
|
||||
import { SetupHandle, SetSize, ResetPosition } from '@/services/Windows';
|
||||
import Api from '@/services/Api'
|
||||
@ -32,7 +36,17 @@ function RefreshUsers(){
|
||||
let users = response.data.users;
|
||||
elements.value = [];
|
||||
users.forEach(user => {
|
||||
console.log(user);
|
||||
if(user.setupCode){
|
||||
elements.value.push({
|
||||
name: t('register-account.pending-account'),
|
||||
_id: user._id,
|
||||
info: {
|
||||
name: t('register-account.pending-account')
|
||||
},
|
||||
user
|
||||
})
|
||||
} else elements.value.push({
|
||||
name: user.username,
|
||||
_id: user._id,
|
||||
info: {
|
||||
@ -51,10 +65,18 @@ async function ElementIcon(element){
|
||||
}
|
||||
|
||||
function OpenAccount(data){
|
||||
if(data.user.setupCode){
|
||||
CreateChildWindow(id, 'copy_pending_user_window', {
|
||||
code: data.user.setupCode,
|
||||
id: 'copy_pending_user_window',
|
||||
close: () => ClearWindow('copy_pending_user_window')
|
||||
});
|
||||
} else {
|
||||
CreateChildWindow(id, 'edit_profile', {
|
||||
user: toRaw(data.user),
|
||||
close: () => {ClearWindow('edit_profile');}
|
||||
close: () => ClearWindow('edit_profile')
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function OpenCreateAccount(){
|
||||
|
42
client/src/views/windows/settings/CopyPendingUserWindow.vue
Normal file
42
client/src/views/windows/settings/CopyPendingUserWindow.vue
Normal file
@ -0,0 +1,42 @@
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
const { t } = useI18n()
|
||||
|
||||
import { onMounted, ref, shallowRef, toRaw } from 'vue';
|
||||
import { SetupHandle, SetSize, ResetPosition } from '@/services/Windows';
|
||||
|
||||
import WindowHandle from '@/views/partials/WindowHandle.vue';
|
||||
|
||||
const handle = ref(null);
|
||||
|
||||
const props = defineProps(['data']);
|
||||
const data = props.data;
|
||||
|
||||
let id = data.id;
|
||||
|
||||
onMounted(() => {
|
||||
SetupHandle(id, handle);
|
||||
SetSize(id, {width: 500, height: 380});
|
||||
ResetPosition(id, "center");
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div class="window-wrapper" :id="'window-wrapper-' + id">
|
||||
<WindowHandle :window="id" ref="handle"></WindowHandle>
|
||||
|
||||
<h1>Hola</h1>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<style scoped>
|
||||
.window-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
@ -32,18 +32,13 @@ let title = data.title;
|
||||
|
||||
onMounted(() => {
|
||||
SetupHandle(id, handle);
|
||||
SetSize(id, {width: 500, height: 430});
|
||||
SetSize(id, {width: 400, height: 310});
|
||||
ResetPosition(id, "center");
|
||||
});
|
||||
|
||||
|
||||
function register(){
|
||||
Api().post('/user/register',
|
||||
{
|
||||
name: name.value,
|
||||
username: username.value,
|
||||
email: email.value,
|
||||
}).then((response) => {
|
||||
Api().post('/user/register').then((response) => {
|
||||
const data = response.data;
|
||||
console.log(data);
|
||||
if(data.error){
|
||||
@ -71,19 +66,6 @@ function register(){
|
||||
<div class="document" v-html="t('register-account.welcome-message')">
|
||||
</div>
|
||||
<form v-on:submit.prevent="register">
|
||||
<div class="form-field">
|
||||
<label for="name">{{$t('general.name')}}</label>
|
||||
<input id="name-field" type="text" :placeholder="t('placeholders.name')" name="name" v-model="name" autocomplete="off" >
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="email">{{$t('general.email')}}</label>
|
||||
<input id="email-field" type="email" :placeholder="t('placeholders.email')" name="email" v-model="email" autocomplete="off" >
|
||||
</div>
|
||||
|
||||
<div class="form-field">
|
||||
<label for="username">{{$t('general.username')}}</label>
|
||||
<input id="username-field" type="text" :placeholder="t('placeholders.username')" name="username" v-model="username" autocomplete="off" >
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<button class="btn-primary sound-click confirm-form-button">{{$t('general.register')}}</button>
|
||||
</div>
|
||||
|
@ -37,7 +37,8 @@
|
||||
},
|
||||
"register-account": {
|
||||
"title": "Create new user account",
|
||||
"welcome-message": "<h1>Hola</h1>"
|
||||
"welcome-message": "<h1>Hola</h1>",
|
||||
"pending-account": "Pending account"
|
||||
},
|
||||
"main-menu": {
|
||||
"title": "Dragonroll",
|
||||
|
@ -37,7 +37,8 @@
|
||||
},
|
||||
"register-account": {
|
||||
"title": "Create new user account",
|
||||
"welcome-message": "<p>Here you can create a new user account. The first time the user logs in will be prompted to set his password</p><hr>"
|
||||
"welcome-message": "<p>Here you can create a new user account.</p><br><p>Once you have registered a new account, you will recieve a link that you must give to the owner of the new account. From there, the owner will be able to setup his new account</p><hr>",
|
||||
"pending-account": "Pending account"
|
||||
},
|
||||
"main-menu": {
|
||||
"title": "Dragonroll",
|
||||
|
@ -37,7 +37,8 @@
|
||||
},
|
||||
"register-account": {
|
||||
"title": "Create new user account",
|
||||
"welcome-message": "<h1>Hola</h1>"
|
||||
"welcome-message": "<h1>Hola</h1>",
|
||||
"pending-account": "Pending account"
|
||||
},
|
||||
"main-menu": {
|
||||
"title": "Dragonroll",
|
||||
|
Loading…
Reference in New Issue
Block a user