diff --git a/backend/config/middleware.js b/backend/config/middleware.js
index 2e389ed9..23d65df3 100644
--- a/backend/config/middleware.js
+++ b/backend/config/middleware.js
@@ -1,5 +1,6 @@
const Campaign = require("../models/Campaign");
const CampaignUser = require("../models/CampaignUser");
+const User = require("../models/User");
function hasCampaign(req, res, next){
Campaign.findById(req.query.campaign).lean().then((campaign) => {
@@ -16,11 +17,17 @@ function hasCampaign(req, res, next){
}).catch((err) => res.json({status: "error", err}));
}
-function hasUser(req, res, next){
-
+function isAdmin(req, res, next){
+ User.findOne(req.user).lean().then((user) => {
+ if(user.admin){
+ next();
+ return;
+ }
+ res.json({status: "error", msg: "unauthorized"});
+ }).catch((err) => res.json({status: "error", err}));
}
module.exports = {
hasCampaign,
- hasUser
+ isAdmin
}
\ No newline at end of file
diff --git a/backend/routes/admin.js b/backend/routes/admin.js
new file mode 100644
index 00000000..f6e00eea
--- /dev/null
+++ b/backend/routes/admin.js
@@ -0,0 +1,17 @@
+const express = require('express');
+const router = express.Router();
+
+const { isAdmin } = require('../config/middleware');
+const User = require("../models/User");
+
+router.get('/users', isAdmin, (req, res) => {
+ console.log("HJDSHAKJDHKH")
+ User.find({}).then((users) => {
+ console.log("HJDSHAKJDHKH2")
+ res.json({
+ users
+ });
+ });
+})
+
+module.exports = router;
\ No newline at end of file
diff --git a/backend/routes/concept.js b/backend/routes/concept.js
index 7934765d..44063364 100644
--- a/backend/routes/concept.js
+++ b/backend/routes/concept.js
@@ -1,10 +1,6 @@
const express = require('express');
const router = express.Router();
-const passport = require('passport');
-
-const Campaign = require("../models/Campaign");
-const CampaignUser = require("../models/CampaignUser");
const Concept = require('../models/Concept');
const { hasCampaign } = require('../config/middleware');
const { getIo } = require('../io/socket');
diff --git a/backend/server.js b/backend/server.js
index 8ae5d685..37e753ed 100755
--- a/backend/server.js
+++ b/backend/server.js
@@ -73,6 +73,7 @@ app.use(checkAuth);
app.use('/campaign', require('./routes/campaign'));
app.use('/maps', require('./routes/map'))
app.use('/concept', require('./routes/concept'))
+app.use('/admin', require('./routes/admin'))
// GET localhost:8081/concept/list
// SETUP IO
diff --git a/client/src/assets/main.css b/client/src/assets/main.css
index b846d70a..b173897a 100644
--- a/client/src/assets/main.css
+++ b/client/src/assets/main.css
@@ -221,6 +221,11 @@ button:active {
width: 100%;
}
+.document.centered {
+ text-align: center;
+ justify-content: center;
+}
+
.document.item {
text-align: center;
width: 220px;
diff --git a/client/src/services/Plugins.js b/client/src/services/Plugins.js
index a864910d..b4503c23 100644
--- a/client/src/services/Plugins.js
+++ b/client/src/services/Plugins.js
@@ -23,11 +23,14 @@ async function FetchPlugins(){
name: pluginData.name,
_id: pluginName,
info: {
-
+ name: pluginData.name,
+ description: pluginData.description,
+ authors: pluginData.authors,
+ version: pluginData.version,
}
});
- import(/* @vite-ignore */ `../../plugins/${pluginName}/${pluginData.entrypoint}`).then(module => {
+ import(/* @vite-ignore */ `../../plugins/${pluginName}/${pluginData.client.entrypoint}`).then(module => {
module.Main({
Dragonroll,
Chat,
diff --git a/client/src/services/Windows.js b/client/src/services/Windows.js
index 285a94ee..23feba51 100644
--- a/client/src/services/Windows.js
+++ b/client/src/services/Windows.js
@@ -29,6 +29,7 @@ import IconSelectorWindow from '@/views/windows/selectors/IconSelectorWindow.vue
import DatabaseWindow from '@/views/windows/game/DatabaseWindow.vue'
import AccountManagementWindow from '@/views/windows/settings/AccountManagementWindow.vue'
import PluginManagementWindow from '@/views/windows/settings/PluginManagementWindow.vue'
+import PluginWindow from '../views/windows/settings/PluginWindow.vue';
let windowMap = {
test: ExampleWindow,
@@ -56,7 +57,8 @@ let windowMap = {
icon_selector: IconSelectorWindow,
database: DatabaseWindow,
plugin_management: PluginManagementWindow,
- account_management: AccountManagementWindow
+ account_management: AccountManagementWindow,
+ plugin_window: PluginWindow
};
async function InjectWindow(plugin, window_type, window_component){
diff --git a/client/src/views/partials/BigIconTemplate.vue b/client/src/views/partials/BigIconTemplate.vue
new file mode 100644
index 00000000..9bdf28c3
--- /dev/null
+++ b/client/src/views/partials/BigIconTemplate.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
{{props.title}}
+
![]()
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/src/views/partials/ConceptEntry.vue b/client/src/views/partials/ConceptEntry.vue
index 8a24a9d0..c87f4d04 100644
--- a/client/src/views/partials/ConceptEntry.vue
+++ b/client/src/views/partials/ConceptEntry.vue
@@ -11,15 +11,15 @@ const elementDiv = ref(null);
const tooltipContainer = ref(null);
const icon = ref("icons/game-icons/ffffff/lorc/crossed-swords.svg")
-function updateElement(){
+async function updateElement(){
element.value = props.element;
// Do whatever
let desc = element.value.info.description;
desc = desc ? marked.parse(desc) : '';
- if(props.icon) icon.value = props.icon(element.value);
+ if(props.icon) icon.value = await props.icon(element.value);
- let tooltip = props.tooltip(element.value);
+ let tooltip = await props.tooltip(element.value);
if(tooltip) AddTooltip(tooltipContainer.value, tooltip);
}
diff --git a/client/src/views/partials/ConceptList.vue b/client/src/views/partials/ConceptList.vue
index 4250d516..571fa440 100644
--- a/client/src/views/partials/ConceptList.vue
+++ b/client/src/views/partials/ConceptList.vue
@@ -52,9 +52,9 @@ function onLeave(el, done) {
diff --git a/client/src/views/windows/game/DatabaseWindow.vue b/client/src/views/windows/game/DatabaseWindow.vue
index f3ba58c8..9d5ed6f1 100644
--- a/client/src/views/windows/game/DatabaseWindow.vue
+++ b/client/src/views/windows/game/DatabaseWindow.vue
@@ -39,7 +39,6 @@ function OpenCreateItemPrompt(){
function OpenConcept(element){
- console.log(`${GetCampaignModuleName()}/item_sheet`);
CreateWindow(`${GetCampaignModuleName()}/item_sheet`, {
id: 'item_sheet_' + element._id,
title: 'Edit Item',
@@ -49,7 +48,6 @@ function OpenConcept(element){
}
function ElementContext(element){
- console.log(element);
return [
{name: "Open"},
{name: "Delete"}
diff --git a/client/src/views/windows/settings/AccountManagementWindow.vue b/client/src/views/windows/settings/AccountManagementWindow.vue
index 50dd181c..fe4b4e99 100644
--- a/client/src/views/windows/settings/AccountManagementWindow.vue
+++ b/client/src/views/windows/settings/AccountManagementWindow.vue
@@ -1,8 +1,13 @@
@@ -26,8 +50,14 @@ onMounted(() => {
-
+
+
+
+
@@ -37,6 +67,14 @@ onMounted(() => {
display: flex;
align-items: center;
}
+
+.fixed-bottom-buttons {
+ position: absolute;
+ bottom: 10px;
+ right: 10px;
+ z-index: 2;
+ display: flex;
+}
diff --git a/client/src/views/windows/settings/PluginManagementWindow.vue b/client/src/views/windows/settings/PluginManagementWindow.vue
index d3e2a9b8..4148ff5f 100644
--- a/client/src/views/windows/settings/PluginManagementWindow.vue
+++ b/client/src/views/windows/settings/PluginManagementWindow.vue
@@ -5,7 +5,7 @@ import { SetupHandle, SetSize, ResetPosition } from '@/services/Windows';
import WindowHandle from '@/views/partials/WindowHandle.vue';
import ConceptList from '../../partials/ConceptList.vue';
import { _GetPlugins } from '../../../services/Plugins';
-import { SetMinSize, SetResizable } from '../../../services/Windows';
+import { ClearWindow, CreateChildWindow, SetMinSize, SetResizable } from '../../../services/Windows';
const handle = ref(null);
@@ -32,6 +32,16 @@ onMounted(() => {
function GetPluginIcon(plugin){
return `/plugins/${plugin._id}/icon.png`;
}
+
+function OpenPlugin(plugin){
+ CreateChildWindow(id, '', {
+ type: 'plugin_window',
+ id: 'plugin-window-' + plugin._id,
+ title: plugin.name,
+ plugin,
+ close: () => ClearWindow('plugin-window-' + plugin._id)
+ })
+}
@@ -43,6 +53,7 @@ function GetPluginIcon(plugin){
diff --git a/client/src/views/windows/settings/PluginWindow.vue b/client/src/views/windows/settings/PluginWindow.vue
new file mode 100644
index 00000000..2d45da81
--- /dev/null
+++ b/client/src/views/windows/settings/PluginWindow.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/dnd-5e/client/main.js b/plugins/dnd-5e/client/main.js
index 4b019c0a..627afb4d 100644
--- a/plugins/dnd-5e/client/main.js
+++ b/plugins/dnd-5e/client/main.js
@@ -14,7 +14,7 @@ function Main(Api){
"name": "Aran Roig"
}
],
- "version": "1.0.0",
+ "version": "0.1",
"color": "#e92026"
});
diff --git a/plugins/dnd-5e/client/plugin.json b/plugins/dnd-5e/client/plugin.json
deleted file mode 100644
index c2fb93e9..00000000
--- a/plugins/dnd-5e/client/plugin.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "Dnd 5e System",
- "entrypoint": "main.js"
-}
\ No newline at end of file
diff --git a/plugins/dnd-5e/client/views/CreateItemPrompt.vue b/plugins/dnd-5e/client/views/CreateItemPrompt.vue
index 8d7c6556..834d47d1 100644
--- a/plugins/dnd-5e/client/views/CreateItemPrompt.vue
+++ b/plugins/dnd-5e/client/views/CreateItemPrompt.vue
@@ -4,6 +4,7 @@ import WindowHandle from '@/views/partials/WindowHandle.vue';
import { onMounted, ref } from 'vue';
import { SetupHandle, SetSize, ResetPosition } from '@/services/Windows';
import { ClearWindow, CreateWindow } from '@/services/Windows';
+import { GetCampaignModuleName } from '../../../../client/src/services/Campaign';
const props = defineProps(['data']);
const data = props.data;
@@ -23,7 +24,7 @@ function ConfirmSelection(){
if(!selected) return;
let value = selected.value;
- CreateWindow('item_sheet', {
+ CreateWindow(`${GetCampaignModuleName()}/item_sheet`, {
id: 'item_sheet',
title: 'Edit Item',
item_type: value,
diff --git a/plugins/dnd-5e/plugin.json b/plugins/dnd-5e/plugin.json
new file mode 100644
index 00000000..85abcb4d
--- /dev/null
+++ b/plugins/dnd-5e/plugin.json
@@ -0,0 +1,13 @@
+{
+ "name": "Dnd 5e System",
+ "description": "This plugin provides the Dnd 5e module",
+ "authors": [
+ {
+ "name": "Aran Roig"
+ }
+ ],
+ "version": "0.1",
+ "client": {
+ "entrypoint": "main.js"
+ }
+}
\ No newline at end of file
diff --git a/plugins/example/client/plugin.json b/plugins/example/client/plugin.json
deleted file mode 100644
index 253a6c54..00000000
--- a/plugins/example/client/plugin.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "Dragonroll example plugin",
- "entrypoint": "main.js"
-}
\ No newline at end of file
diff --git a/plugins/example/plugin.json b/plugins/example/plugin.json
new file mode 100644
index 00000000..32f58e8a
--- /dev/null
+++ b/plugins/example/plugin.json
@@ -0,0 +1,13 @@
+{
+ "name": "Dragonroll example plugin",
+ "description": "This is an example plugin to help you getting started with the Dragonroll API",
+ "authors": [
+ {
+ "name": "Aran Roig"
+ }
+ ],
+ "version": "0.1",
+ "client": {
+ "entrypoint": "main.js"
+ }
+}
\ No newline at end of file
diff --git a/prebuild.js b/prebuild.js
index 90772d29..48d0c217 100755
--- a/prebuild.js
+++ b/prebuild.js
@@ -94,6 +94,7 @@ console.log("Updated Locales")
for(let j = 0; j < plugins.length; j++){
if(fs.existsSync(`./plugins/${plugins[j]}/client/`)){
fs.cpSync(`./plugins/${plugins[j]}/client/`, `./client/plugins/${plugins[j]}`, {recursive: true});
+ fs.copyFileSync(`./plugins/${plugins[j]}/plugin.json`, `./client/plugins/${plugins[j]}/plugin.json`);
}
if(fs.existsSync(`./plugins/${plugins[j]}/public/`)){