Compare commits
13 Commits
ac545ed61c
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8eb43ac7b5 | ||
|
|
b7e6adda06 | ||
|
|
378c3da58f | ||
|
|
5deca0ad4f | ||
|
|
5e802c4577 | ||
|
|
d3207daf2b | ||
|
|
64ed506baf | ||
|
|
76e51f0f46 | ||
|
|
1bfe4b3995 | ||
|
|
aa5a29123c | ||
|
|
84f0dcca94 | ||
|
|
b78cb59a51 | ||
|
|
023eebdc50 |
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -1,3 +1,3 @@
|
|||||||
[submodule "gancio_plugins/gancio-plugin-telegram-bridge"]
|
[submodule "gancio_plugins/gancio-plugin-telegram-bridge"]
|
||||||
path = gancio_plugins/gancio-plugin-telegram-bridge
|
path = gancio_plugins/gancio-plugin-telegram-bridge
|
||||||
url = https://framagit.org/bcn.convocala/gancio-plugin-telegram-bridge.git
|
url = https://framagit.org/bcn.convocala/gancio-plugin-telegram-bridge
|
||||||
|
|||||||
12
CHANGELOG
12
CHANGELOG
@@ -1,5 +1,17 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
### 1.6.14 - 30 June '23
|
||||||
|
- improve CLI accounts operations ([documentation](https://gancio.org/usage/cli))
|
||||||
|
- allow plugins to expose API ([documentation](http://gancio.org/dev/plugins))
|
||||||
|
- allow plugins to access DB ([documentation](http://gancio.org/dev/plugins))
|
||||||
|
- show map on the places page, #276 #30
|
||||||
|
- add node v18 support, #278
|
||||||
|
- fix media update, #285
|
||||||
|
- fix nodejs v14 compatibility in export
|
||||||
|
- fix invalid event microdata, #277
|
||||||
|
- fix recurrent event, #280
|
||||||
|
- update deps and locales
|
||||||
|
|
||||||
### 1.6.13 - 16 may '23
|
### 1.6.13 - 16 may '23
|
||||||
- fix feed, ics, json exports
|
- fix feed, ics, json exports
|
||||||
|
|
||||||
|
|||||||
BIN
docs/assets/plugins/settings.png
Normal file
BIN
docs/assets/plugins/settings.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
@@ -8,6 +8,18 @@ nav_order: 10
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
### 1.6.14 - 30 June '23
|
||||||
|
- improve CLI accounts operations ([documentation](https://gancio.org/usage/cli))
|
||||||
|
- allow plugins to expose API ([documentation](http://gancio.org/dev/plugins))
|
||||||
|
- allow plugins to access DB ([documentation](http://gancio.org/dev/plugins))
|
||||||
|
- show map on the places page, [#276]((https://framagit.org/les/gancio/-/issues/276)) #30
|
||||||
|
- add node v18 support, [#278]((https://framagit.org/les/gancio/-/issues/278))
|
||||||
|
- fix media update, [#285]((https://framagit.org/les/gancio/-/issues/285))
|
||||||
|
- fix nodejs v14 compatibility in export
|
||||||
|
- fix invalid event microdata, [#277]((https://framagit.org/les/gancio/-/issues/277))
|
||||||
|
- fix recurrent event, [#280]((https://framagit.org/les/gancio/-/issues/280))
|
||||||
|
- update deps and locales
|
||||||
|
|
||||||
### 1.6.13 - 16 may '23
|
### 1.6.13 - 16 may '23
|
||||||
- fix feed, ics, json exports
|
- fix feed, ics, json exports
|
||||||
|
|
||||||
|
|||||||
@@ -16,16 +16,110 @@ Since **v.1.2.2** you can write your own plugin that react to event related acti
|
|||||||
>
|
>
|
||||||
> [**<u>Please share your plugins or your needs</u>**](/contacts)
|
> [**<u>Please share your plugins or your needs</u>**](/contacts)
|
||||||
|
|
||||||
Plugins should be inside `./plugins` directory, this is an example:
|
|
||||||
|
## Example
|
||||||
|
Here is a complete example of plugins feature: [https://framagit.org/les/gancio/-/blob/master/plugins/gancioPluginExample.js](https://framagit.org/les/gancio/-/blob/master/plugins/gancioPluginExample.js) .
|
||||||
|
|
||||||
|
## Basic plugin syntax
|
||||||
|
|
||||||
|
A plugin is essentially an `index.js` file inside its own path in `./plugins`, e.g. `./plugins/my-example-plugin/index.js`
|
||||||
|
```javascript
|
||||||
|
module.exports = {
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Plugins should be inside `./plugins` directory but you can specify another location using [`plugins_path`](https://gancio.org/install/config#plugins-path) configuration.
|
||||||
|
|
||||||
|
## Plugin details
|
||||||
|
A plugins **MUST** expose a `configuration` key where to specify its details:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const plugin = {
|
module.exports = {
|
||||||
gancio: null,
|
configuration: {
|
||||||
load (gancio) {
|
name: 'Example',
|
||||||
console.error('Plugin GancioPluginExample loaded!')
|
author: 'lesion',
|
||||||
plugin.gancio = gancio
|
url: 'https://framagit.org/les/gancio/plugins/gancioPluginExample.js',
|
||||||
},
|
description: 'Example plugin',
|
||||||
|
settings: {
|
||||||
|
my_plugin_string_setting: {
|
||||||
|
type: 'TEXT',
|
||||||
|
description: 'My plugin string setting',
|
||||||
|
required: true,
|
||||||
|
hint: 'My plugin setting support <strong>html too</strong>'
|
||||||
|
},
|
||||||
|
enable_this_feature_in_my_plugin: {
|
||||||
|
type: 'CHECK',
|
||||||
|
description: 'My plugin best feature',
|
||||||
|
required: true,
|
||||||
|
hint: 'This feature is super dupe, enable it!'
|
||||||
|
},
|
||||||
|
min_post: {
|
||||||
|
type: 'NUMBER',
|
||||||
|
description: 'it supports number too'
|
||||||
|
},
|
||||||
|
my_default_language: {
|
||||||
|
description: 'My default language',
|
||||||
|
type: 'LIST',
|
||||||
|
items: ['it', 'en', 'fr']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[](/assets/plugins/settings.png){: data-fancybox="group" data-caption="Home"}
|
||||||
|
|
||||||
|
|
||||||
|
## Load a plugin
|
||||||
|
When a plugin is enabled by an administrator, Gancio will call the `load` method if specified:
|
||||||
|
|
||||||
|
```js
|
||||||
|
load ({ settings: gancio_settings, db, helpers, log}, settings) {
|
||||||
|
|
||||||
|
// access to your plugin local settings
|
||||||
|
console.info('Your local settings are in ', settings)
|
||||||
|
console.info(`For example, you can access to your default language setting by using ${settings.my_default_language}`)
|
||||||
|
|
||||||
|
// access to gancio settings
|
||||||
|
console.info(`Gancio settings are in ${gancio_settings}, e.g. ${gancio.settings.baseurl}`)
|
||||||
|
|
||||||
|
// log something
|
||||||
|
log.warn('This is a log entry from my example plugin')
|
||||||
|
|
||||||
|
// use the DB (since 1.6.14)
|
||||||
|
console.info(db.models.findAll())
|
||||||
|
console.info(db.query('CREATE TABLE IF NOT EXISTS myPluginTable'))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Expose an API <span class='label label-yellow'>since 1.6.4</span>
|
||||||
|
|
||||||
|
Plugins could have public HTTP endpoints by exposing an express Router in routeAPI object.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const express = require('express')
|
||||||
|
const routeAPI = express.Router()
|
||||||
|
|
||||||
|
routeAPI.get('/test', (req, res) => {
|
||||||
|
res.json('WOW!')
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
This endpoint will be exposed at <your_instance>/api/plugin/<your_plugin_name>/test
|
||||||
|
|
||||||
|
|
||||||
|
## Access to DB <span class='label label-yellow'>since 1.6.4</span>
|
||||||
|
TODO
|
||||||
|
|
||||||
|
## Helpers <span class='label label-red'>DOCUMENTATION NEEDED</span>
|
||||||
|
- randomString
|
||||||
|
- sanitizeHTML
|
||||||
|
- queryParamToBool
|
||||||
|
|
||||||
|
## React to events
|
||||||
|
|
||||||
|
```js
|
||||||
onEventCreate (event) {
|
onEventCreate (event) {
|
||||||
const eventLink = `${plugin.gancio.settings.baseurl}/event/${event.slug}`
|
const eventLink = `${plugin.gancio.settings.baseurl}/event/${event.slug}`
|
||||||
if (!event.is_visible) {
|
if (!event.is_visible) {
|
||||||
@@ -42,10 +136,6 @@ const plugin = {
|
|||||||
onEventDelete (event) {
|
onEventDelete (event) {
|
||||||
console.error(`Event "${event.title}" deleted`)
|
console.error(`Event "${event.title}" deleted`)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = plugin
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ permalink: /
|
|||||||
|
|
||||||
A shared agenda for local communities.
|
A shared agenda for local communities.
|
||||||
{: .fs-6 }
|
{: .fs-6 }
|
||||||
Last release **[1.6.13 - 16 May 2023](/changelog#1613---16-may-23)**
|
Last release **[1.6.14 - 30 June 2023](/changelog#1614---30-june-23)**
|
||||||
|
|
||||||
[Install]({% link install/install.md %}){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }
|
[Install]({% link install/install.md %}){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }
|
||||||
[Demo](https://demo.gancio.org){: .btn .btn-green .fs-5 .mb-4 .mb-md-0 .mr-2 }
|
[Demo](https://demo.gancio.org){: .btn .btn-green .fs-5 .mb-4 .mb-md-0 .mr-2 }
|
||||||
|
|||||||
60
docs/usage/cli.md
Normal file
60
docs/usage/cli.md
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title: CLI
|
||||||
|
permalink: /usage/cli
|
||||||
|
nav_order: 2
|
||||||
|
parent: Usage
|
||||||
|
has_toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# CLI - Command Line Interface
|
||||||
|
{: .no_toc }
|
||||||
|
|
||||||
|
1. TOC
|
||||||
|
{:toc}
|
||||||
|
|
||||||
|
## Using CLI
|
||||||
|
Gancio is distributed with an embedded CLI.
|
||||||
|
To use the CLI you need to specify the `config.json` configuration file via `--config <your_config.json>` flag; by default the CLI will look for one in the current directory, so if your current directory is /opt/gancio (having followed the [installation instructions](/install/debian)) there is no need to specify it.
|
||||||
|
|
||||||
|
### Using CLI with Docker installation
|
||||||
|
To use the CLI in a docker installation you can execute a shell inside the container with:
|
||||||
|
`docker exec --workdir /home/node/data -it gancio sh` and following the normal CLI usage or running commands with:
|
||||||
|
|
||||||
|
`docker exec --workdir /home/node/data gancio gancio <your command>`
|
||||||
|
|
||||||
|
(the first "gancio" is the container name)
|
||||||
|
|
||||||
|
|
||||||
|
## Users <span class='label label-yellow'>since 1.6.14</span>
|
||||||
|
All users related sub-commands starts with `gancio users`.
|
||||||
|
Note that most of this actions could be done from administration panel (Admin > Users).
|
||||||
|
|
||||||
|
|
||||||
|
### List all users
|
||||||
|
To list all users use
|
||||||
|
`gancio users list`
|
||||||
|
|
||||||
|
|
||||||
|
### Create a new user
|
||||||
|
|
||||||
|
`gancio users create <username|email>`
|
||||||
|
|
||||||
|
To create an user with administrator privileges use the `--admin` flag, e.g. `gancio users create admin@example.com --admin`
|
||||||
|
|
||||||
|
|
||||||
|
### Remove a user
|
||||||
|
`gancio users remove <username|email>`
|
||||||
|
|
||||||
|
|
||||||
|
### Reset password
|
||||||
|
`gancio users reset-password <username|email>`
|
||||||
|
|
||||||
|
|
||||||
|
### Change administrator privileges
|
||||||
|
|
||||||
|
To add administrator privileges to an user:
|
||||||
|
`gancio users set-admin <username|email>`
|
||||||
|
|
||||||
|
To remove administrator privileges from an user:
|
||||||
|
`gancio users unset-admin <username|email>`
|
||||||
@@ -10,13 +10,12 @@ has_toc: true
|
|||||||
# Plugins
|
# Plugins
|
||||||
{: .no_toc }
|
{: .no_toc }
|
||||||
|
|
||||||
This page is a guide to install plugins, if you want to develop one instead look [here](/dev/plugins)
|
This page is a guide to install plugins, if you want to develop one instead look [here](/dev/plugins).
|
||||||
|
__Please note that some plugins are officially supported and distributed along with the release__
|
||||||
|
|
||||||
1. TOC
|
1. TOC
|
||||||
{:toc}
|
{:toc}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
To install a plugin you have to:
|
To install a plugin you have to:
|
||||||
@@ -49,7 +48,7 @@ __with docker__
|
|||||||
docker-compose restart
|
docker-compose restart
|
||||||
```
|
```
|
||||||
|
|
||||||
# List of plugins
|
# List of embedded plugins
|
||||||
|
|
||||||
## __Telegram__
|
## __Telegram__
|
||||||
|
|
||||||
@@ -57,6 +56,5 @@ This plugin republishes events to Telegram channels or groups.
|
|||||||
The goal is to spread the info of our networks to the capitalist cyberspace, and pull otherwise isolated people to our radical and free part of the internet.
|
The goal is to spread the info of our networks to the capitalist cyberspace, and pull otherwise isolated people to our radical and free part of the internet.
|
||||||
|
|
||||||
- **Website**: [https://framagit.org/bcn.convocala/gancio-plugin-telegram-bridge](https://framagit.org/bcn.convocala/gancio-plugin-telegram-bridge)
|
- **Website**: [https://framagit.org/bcn.convocala/gancio-plugin-telegram-bridge](https://framagit.org/bcn.convocala/gancio-plugin-telegram-bridge)
|
||||||
- **Download**: [gancio-plugin-telegram-bridge-v0.2.0.zip](https://framagit.org/les/gancio-plugin-telegram-bridge/-/archive/v0.2.0/gancio-plugin-telegram-bridge-v0.2.0.zip)
|
- **Release**: https://framagit.org/bcn.convocala/gancio-plugin-telegram-bridge/-/commit/af0eed7b42242ba484d9828157f1be0355bba69b
|
||||||
- **Release**: v0.2.0 / 10 Dec '22
|
|
||||||
|
|
||||||
|
|||||||
Submodule gancio_plugins/gancio-plugin-telegram-bridge updated: 971ea23b6a...af0eed7b42
@@ -8,22 +8,22 @@
|
|||||||
"subject": "Você pode agora começar a publicar eventos"
|
"subject": "Você pode agora começar a publicar eventos"
|
||||||
},
|
},
|
||||||
"event_confirm": {
|
"event_confirm": {
|
||||||
"content": "Você pode confirmar este evento <a href='{{url}}'>nesta página</a>"
|
"content": "Pode confirmar este evento <a href='{{url}}'>nesta página</a>"
|
||||||
},
|
},
|
||||||
"test": {
|
"test": {
|
||||||
"subject": "Sua configuração SMTP está funcionando",
|
"subject": "A sua configuração SMTP funciona",
|
||||||
"content": "Este é um e-mail de teste, se estiver lendo isto, sua configuração está funcionando."
|
"content": "Este é um e-mail de teste, se estiver a ler isto, a sua configuração funciona."
|
||||||
},
|
},
|
||||||
"user_confirm": {
|
"user_confirm": {
|
||||||
"subject": "Você pode agora começar a publicar eventos",
|
"subject": "Você pode agora começar a publicar eventos",
|
||||||
"content": "Olá, sua conta em <a href='{{config.baseurl}}'>{{config.title}}</a> foi criada. <a href='{{config.baseurl}}/user_confirm/{{user.recover_code}}'>Confirme e escolha uma senha.</a>."
|
"content": "Olá, a sua conta em <a href='{{config.baseurl}}'>{{config.title}}</a> foi criada. <a href='{{config.baseurl}}/user_confirm/{{user.recover_code}}'>Confirme e escolha uma palavra-passe.</a>."
|
||||||
},
|
},
|
||||||
"admin_register": {
|
"admin_register": {
|
||||||
"subject": "Novo registro",
|
"subject": "Novo registo",
|
||||||
"content": "{{user.email}} pediu o registro em {{config.title}}: <br/><pre>{{user.description}}</pre><br/> Confirme <a href='{{config.baseurl}}/admin'>aqui</a>."
|
"content": "{{user.email}} pediu o registo em {{config.title}}: <br/><pre>{{user.description}}</pre><br/> Confirme <a href='{{config.baseurl}}/admin'>aqui</a>."
|
||||||
},
|
},
|
||||||
"recover": {
|
"recover": {
|
||||||
"subject": "Recuperação de senha",
|
"subject": "Recuperação da palavra-passe",
|
||||||
"content": "Olá, você solicitou a recuperação de sua senha em {{config.title}}. <a href='{{config.baseurl}}/recover/{{user.recover_code}}'>Clique aqui</a> para confirmar."
|
"content": "Olá, solicitou a recuperação da sua palavra-passe em {{config.title}}. <a href='{{config.baseurl}}/recover/{{user.recover_code}}'>Clique aqui</a> para confirmar."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gancio",
|
"name": "gancio",
|
||||||
"version": "1.6.13",
|
"version": "1.6.14",
|
||||||
"description": "A shared agenda for local communities",
|
"description": "A shared agenda for local communities",
|
||||||
"author": "lesion",
|
"author": "lesion",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,9 +1,62 @@
|
|||||||
|
const express = require('express')
|
||||||
|
const myPluginRouter = express.Router()
|
||||||
|
|
||||||
|
// this will answer at http://localhost:13120/api/plugin/Example/test
|
||||||
|
myPluginRouter.get('/test', (req, res) => {
|
||||||
|
return res.json('OK!')
|
||||||
|
})
|
||||||
|
|
||||||
const plugin = {
|
const plugin = {
|
||||||
|
routeAPI: myPluginRouter,
|
||||||
|
configuration: {
|
||||||
|
name: 'Example',
|
||||||
|
author: 'lesion',
|
||||||
|
url: 'https://framagit.org/les/gancio',
|
||||||
|
description: 'Example plugin',
|
||||||
|
settings: {
|
||||||
|
my_plugin_string_setting: {
|
||||||
|
type: 'TEXT',
|
||||||
|
description: 'My plugin string setting',
|
||||||
|
required: true,
|
||||||
|
hint: 'My plugin setting support <strong>html too</strong>'
|
||||||
|
},
|
||||||
|
enable_this_feature_in_my_plugin: {
|
||||||
|
type: 'CHECK',
|
||||||
|
description: 'My plugin best feature',
|
||||||
|
required: true,
|
||||||
|
hint: 'This feature is super dupe, enable it!'
|
||||||
|
},
|
||||||
|
min_post: {
|
||||||
|
type: 'NUMBER',
|
||||||
|
description: 'it supports number too'
|
||||||
|
},
|
||||||
|
my_default_language: {
|
||||||
|
description: 'My default language',
|
||||||
|
type: 'LIST',
|
||||||
|
items: ['it', 'en', 'fr']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
gancio: null,
|
gancio: null,
|
||||||
load (gancio) {
|
settings: null,
|
||||||
|
load (gancio, settings) {
|
||||||
console.error('Plugin GancioPluginExample loaded!')
|
console.error('Plugin GancioPluginExample loaded!')
|
||||||
|
console.error('Your settings are in ', settings)
|
||||||
|
console.error(`For example, you can access to your default language setting by using ${settings.my_default_language}`)
|
||||||
plugin.gancio = gancio
|
plugin.gancio = gancio
|
||||||
|
plugin.settings = settings
|
||||||
|
|
||||||
|
// gancio.db.models.event.findAll({ where: })
|
||||||
|
// gancio.db.query('CREATE TABLE IF NOT EXISTS ()... ')
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
unload () {
|
||||||
|
console.error('Unload this plugin!')
|
||||||
|
},
|
||||||
|
|
||||||
|
onTest () {
|
||||||
|
console.error('called on "TEST" button pressed in admin interface')
|
||||||
},
|
},
|
||||||
|
|
||||||
onEventCreate (event) {
|
onEventCreate (event) {
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ const pluginController = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (plugin.unload && typeof plugin.unload === 'function') {
|
if (plugin.unload && typeof plugin.unload === 'function') {
|
||||||
plugin.unload({ settings: settingsController.settings }, settings)
|
plugin.unload()
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
const pkg = require('../package.json')
|
const pkg = require('../package.json')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const accountsCLI = require('./cli/accounts')
|
const usersCLI = require('./cli/users')
|
||||||
|
|
||||||
process.env.cwd = process.env.GANCIO_DATA || path.resolve('./')
|
process.env.cwd = process.env.GANCIO_DATA || path.resolve('./')
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ require('yargs')
|
|||||||
return absolute_config_path
|
return absolute_config_path
|
||||||
}})
|
}})
|
||||||
.command(['start', 'run', '$0'], 'Start gancio', {}, start)
|
.command(['start', 'run', '$0'], 'Start gancio', {}, start)
|
||||||
.command(['accounts'], 'Manage accounts', accountsCLI)
|
.command(['users'], 'Manage users', usersCLI)
|
||||||
.help('h')
|
.help('h')
|
||||||
.alias('h', 'help')
|
.alias('h', 'help')
|
||||||
.epilog('Made with ❤ by underscore hacklab - https://gancio.org')
|
.epilog('Made with ❤ by underscore hacklab - https://gancio.org')
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
let db
|
|
||||||
function _initializeDB () {
|
|
||||||
const config = require('../config')
|
|
||||||
config.log_level = 'error'
|
|
||||||
db = require('../api/models/index')
|
|
||||||
return db.initialize()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function modify (args) {
|
|
||||||
await _initializeDB()
|
|
||||||
const helpers = require('../helpers')
|
|
||||||
const { User } = require('../api/models/models')
|
|
||||||
const user = await User.findOne({ where: { email: args.account } })
|
|
||||||
console.log()
|
|
||||||
if (!user) {
|
|
||||||
console.error(`User ${args.account} not found`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args['reset-password']) {
|
|
||||||
const password = helpers.randomString()
|
|
||||||
user.password = password
|
|
||||||
await user.save()
|
|
||||||
console.log(`New password for user ${user.email} is '${password}'`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.admin) {
|
|
||||||
user.is_admin = true
|
|
||||||
await user.save()
|
|
||||||
}
|
|
||||||
await db.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function create (args) {
|
|
||||||
await _initializeDB()
|
|
||||||
const { User } = require('../api/models/models')
|
|
||||||
const user = await User.create({
|
|
||||||
email: args.email,
|
|
||||||
is_active: true,
|
|
||||||
is_admin: args.admin || false
|
|
||||||
}).catch(e => console.error(String(e)))
|
|
||||||
console.error(JSON.stringify(user, null, 2))
|
|
||||||
await db.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async function remove (args) {
|
|
||||||
await _initializeDB()
|
|
||||||
const { User } = require('../api/models/models')
|
|
||||||
const user = await User.findOne({
|
|
||||||
where: { email: args.email }
|
|
||||||
})
|
|
||||||
if (user) {
|
|
||||||
await user.destroy()
|
|
||||||
}
|
|
||||||
await db.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function list () {
|
|
||||||
await _initializeDB()
|
|
||||||
const { User } = require('../api/models/models')
|
|
||||||
const users = await User.findAll()
|
|
||||||
console.log()
|
|
||||||
users.forEach(u => console.log(`${u.id}\tadmin: ${u.is_admin}\tenabled: ${u.is_active}\temail: ${u.email}`))
|
|
||||||
console.log()
|
|
||||||
await db.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
const accountsCLI = yargs => yargs
|
|
||||||
.command('list', 'List all accounts', list)
|
|
||||||
.command('modify', 'Modify', {
|
|
||||||
account: {
|
|
||||||
describe: 'Account to modify',
|
|
||||||
type: 'string',
|
|
||||||
demandOption: true
|
|
||||||
},
|
|
||||||
'reset-password': {
|
|
||||||
describe: 'Resets the password of the given account ',
|
|
||||||
type: 'boolean'
|
|
||||||
},
|
|
||||||
admin: { describe: 'Define this account as administrator', type: 'boolean' }
|
|
||||||
}, modify)
|
|
||||||
.command('create <email|username> [admin]', 'Create an account', {
|
|
||||||
admin: { describe: 'Define this account as administrator', type: 'boolean' }
|
|
||||||
}, create)
|
|
||||||
.command('remove <email|username>', 'Remove an account', {}, remove)
|
|
||||||
.positional('email', { describe: 'account email or username', type: 'string', demandOption: true })
|
|
||||||
.recommendCommands()
|
|
||||||
.demandCommand(1, '')
|
|
||||||
.argv
|
|
||||||
|
|
||||||
module.exports = accountsCLI
|
|
||||||
114
server/cli/users.js
Normal file
114
server/cli/users.js
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
let db
|
||||||
|
function _initializeDB () {
|
||||||
|
const config = require('../config')
|
||||||
|
config.log_level = 'error'
|
||||||
|
db = require('../api/models/index')
|
||||||
|
return db.initialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setAdmin (args) {
|
||||||
|
await _initializeDB()
|
||||||
|
const { User } = require('../api/models/models')
|
||||||
|
const user = await User.findOne({ where: { email: args.email } })
|
||||||
|
console.log()
|
||||||
|
if (!user) {
|
||||||
|
console.error(`User ${args.email} not found`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
user.is_admin = true
|
||||||
|
await user.save()
|
||||||
|
console.log(`User ${user.email} is now an administrator!`)
|
||||||
|
await db.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function unsetAdmin (args) {
|
||||||
|
await _initializeDB()
|
||||||
|
const helpers = require('../helpers')
|
||||||
|
const { User } = require('../api/models/models')
|
||||||
|
const user = await User.findOne({ where: { email: args.email } })
|
||||||
|
console.log()
|
||||||
|
if (!user) {
|
||||||
|
console.error(`User ${args.email} not found`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
user.is_admin = false
|
||||||
|
await user.save()
|
||||||
|
console.log(`User ${user.email} is not an administrator anymore!`)
|
||||||
|
await db.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function resetPassword (args) {
|
||||||
|
await _initializeDB()
|
||||||
|
const helpers = require('../helpers')
|
||||||
|
const { User } = require('../api/models/models')
|
||||||
|
const user = await User.findOne({ where: { email: args.email } })
|
||||||
|
console.log()
|
||||||
|
if (!user) {
|
||||||
|
console.error(`User ${args.email} not found`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const password = helpers.randomString()
|
||||||
|
user.password = password
|
||||||
|
await user.save()
|
||||||
|
console.log(`New password for user ${user.email} is '${password}'`)
|
||||||
|
await db.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function create (args) {
|
||||||
|
await _initializeDB()
|
||||||
|
const { User } = require('../api/models/models')
|
||||||
|
const user = await User.create({
|
||||||
|
email: args.email,
|
||||||
|
is_active: true,
|
||||||
|
is_admin: args.admin || false
|
||||||
|
}).catch(e => console.error(String(e)))
|
||||||
|
console.error(JSON.stringify(user, null, 2))
|
||||||
|
await db.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function remove (args) {
|
||||||
|
await _initializeDB()
|
||||||
|
const { User } = require('../api/models/models')
|
||||||
|
const user = await User.findOne({
|
||||||
|
where: { email: args.email }
|
||||||
|
})
|
||||||
|
if (user) {
|
||||||
|
await user.destroy()
|
||||||
|
console.error(`User "${args.email}" succesfully removed`)
|
||||||
|
} else {
|
||||||
|
console.error(`User "${args.email}" not found!`)
|
||||||
|
}
|
||||||
|
await db.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function list () {
|
||||||
|
await _initializeDB()
|
||||||
|
const { User } = require('../api/models/models')
|
||||||
|
const users = await User.findAll()
|
||||||
|
console.log()
|
||||||
|
users.forEach(u => console.log(`${u.id}\tadmin: ${u.is_admin}\tenabled: ${u.is_active}\temail: ${u.email}`))
|
||||||
|
console.log()
|
||||||
|
await db.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
const usersCLI = yargs => yargs
|
||||||
|
.command('list', 'List all users', list)
|
||||||
|
.command('reset-password <email|username>', 'Resets the password of the given user', {
|
||||||
|
}, resetPassword)
|
||||||
|
.command('set-admin <email|username>', 'Set administrator privileges to the given user', {}, setAdmin)
|
||||||
|
.command('unset-admin <email|username>', 'Remove administrator privileges to the given user', {}, unsetAdmin)
|
||||||
|
.command('create <email|username> [admin]', 'Create an user', {
|
||||||
|
admin: { describe: 'Define this user as administrator', type: 'boolean' }
|
||||||
|
}, create)
|
||||||
|
.command('remove <email|username>', 'Remove an user', {}, remove)
|
||||||
|
.positional('email', { describe: 'user email or username', type: 'string', demandOption: true })
|
||||||
|
.recommendCommands()
|
||||||
|
.demandCommand(1, '')
|
||||||
|
.argv
|
||||||
|
|
||||||
|
module.exports = usersCLI
|
||||||
Reference in New Issue
Block a user