diff --git a/.gitignore b/.gitignore
index f1a48207..c10afaf8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,13 +1,14 @@
# Created by .ignore support plugin (hsz.mobi)
### Gancio dev configuration
-*.sqlite
+gancio.sqlite
+db.sqlite
releases
wp-plugin/wpgancio
config/development.json
-gancio_config.json
-config.json
-db.sqlite
+/gancio_config.json
+/config.json
+/assets/config.json
thumb
docs/_site
.vscode
diff --git a/CHANGELOG b/CHANGELOG
index 017f7c48..6f5fad7c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,11 +1,77 @@
All notable changes to this project will be documented in this file.
+### UNRELEASED
+ - add CLI support to manage accounts (list / modify / add accounts)
+### 1.4.3 - 10 mar '22
+ - fix [#140](https://framagit.org/les/gancio/-/issues/140) - Invalid date
+ - fix [#141](https://framagit.org/les/gancio/-/issues/141) - Cannot change logo
+ - fix same day events
+ - add missing icons in admin
+ - prepare multisite settings
+ - improve initialization
+ - start unit testing API (it's never too late)
+
+### 1.4.1 - 4 mar '22
+ - add gl/galego locale, thanks @xosem
+ - fix import redirect loop
+ - add missing icons (close, repeat, arrows ...)
+ - turn rss icon into a real link to improve a11y
+ - force seconds to 0 for each events, fix recurring events starting date issue
+ - fix next/prev selection on same datetime events
+ - improve moderation UI (add author and event link + format creation date)
+ - refactoring resource UI from fedi
+
+### 1.4.0 - 9 feb '22
+ - improve Cumulative Layout Shift
+ - remove filename as default media label to avoid leak metadata
+ - add endData to microdata
+ - security fix with filtering settings, avoid sharing SMTP pass with front-end
+ - fix broken SMTP
+ - remove global materialicons / vuetify css, use threeshake and @nuxt/vuetify (really improve lighthouse score)
+ - new Dockerfile using node:17.4-slim as base img (from 1.5Gb to ~800Mb)
+ - add XSS and path traversal mitigation
+ - improve a11y
+ - update deps
+
+### 1.3.3 - 1 feb '22
+ - security fix, avoid sharing smtp pass with front-end
+
+### 1.3.2 - 1 feb '22
+ - fix webcomponent for event without img
+
+### 1.3.1 - 1 feb '22
+ - inherits tags in recurring events [#138](https://framagit.org/les/gancio/-/issues/138)
+ - you can now skip an occurrence of a recurring event
+ - fix `show_recurrent` event in webcomponent and API
+ - add new webcomponent `sidebar` attribute and a [`fullwith` layout](https://gancio.org/usage/embed#embed-event-lists)
+
+### 1.3.0 - 26 gen '22
+ - add mariadb support
+ - add [microdata](https://developer.mozilla.org/en-US/docs/Web/HTML/Microdata) support
+ - support db setup via environment variables (used in updated `docker-compose.yml` files)
+ - improve rss feed:
+ - fix validation
+ - add enclusure media for featured image
+ - add categories
+ - fix typo in export code
+ - add theme attribute to gancio-events webcomponent (dark/light)
+ - increase thumbs quality
+ - improve logo for light theme
+ - improve [wordpress plugin](https://wordpress.org/plugins/wpgancio/)
+ - add \[gancio-event\] and \[gancio-events\] shortcode
+ - allow gancio-events / gancio-event tags in editor
+ - automatically enqueue webcomponent script
+ - tags/places filters are now inclusive not exclusive
+ - fix image undefined alternative text
+ - update documentation, dependencies, translations
+
### 1.2.2 - 7 dic '21
- shiny new gancio-event\[s\] webcomponents => [docs](https://gancio.org/usage/embed)
- - new backend plugin system
+ - new backend plugin system => [docs](https://gancio.org/dev/plugins)
- improve media focal point selection
- improve non-js experience (load img, use native lazy loading)
- improve user_confirm / recover code flow
+ - permit admins to choose user password (usefull on instance without SMTP configuration)
- fix task manager exception
- fix db initialization when a custom setup is used, #131
- remove vue-clipboard2 dependency due to [this](https://github.com/euvl/v-clipboard/issues/18) bug and using a [native with fallback mixin instead](./assets/clipboard.js)
diff --git a/RELEASE.md b/RELEASE.md
index 2736e4cb..73fc626c 100644
--- a/RELEASE.md
+++ b/RELEASE.md
@@ -1,11 +1,7 @@
- change version in package.json
- add changes to CHANGELOG / changelog.md
-- yarn build
-- yarn pack
-- yarn publish
-- yarn doc
+./release.sh
- git add .
- git ci -m 'v...'
- git tag ...
- git push --tags
--
diff --git a/assets/clipboard.js b/assets/clipboard.js
index 6b4f6f54..19b0a33e 100644
--- a/assets/clipboard.js
+++ b/assets/clipboard.js
@@ -12,7 +12,7 @@ export default {
document.execCommand('copy')
document.body.removeChild(el)
}
- this.$root.$message(msg)
+ this.$root.$message(msg, { color: 'success'})
}
}
}
diff --git a/assets/editor.less b/assets/editor.less
deleted file mode 100644
index b7b8c975..00000000
--- a/assets/editor.less
+++ /dev/null
@@ -1,61 +0,0 @@
-
-.editor {
- position: relative;
- overflow-y: auto;
- padding-top: 1.7em;
- scrollbar-width: thin;
-
- &.with-border {
- border: 1px solid #ddd;
- border-radius: 5px;
- }
-
- .content {
- padding: 0px 5px 0px 5px;
- flex: 1;
- scrollbar-width: thin;
- overflow-y: auto;
- }
-
- .menububble {
- position: absolute;
- display: flex;
- overflow: hidden;
- opacity: 0;
- z-index: 1;
- background: #dddddd;
- transform: translateX(-50%);
- border-radius: 3px;
- padding: 0.07rem;
- transition: opacity 0.2s, visibility 0.2s, left .2s, bottom .2s;
- visibility: hidden;
-
- &.is-active {
- opacity: 1;
- visibility: visible;
- }
- input {
- padding: 0;
- margin: 1px;
- display: block;
- border: 0;
- color: #444;
- font-size: .8em;
- border-radius: 3px;
- line-height: 100%;
- transition: width .2s;
- padding-left: 5px;
- flex-grow: 1;
- }
-
- .fa-icon {
- width: auto;
- font-size: 10px;
- height: 1.4em; /* or any other relative font sizes */
- /* You would have to include the following two lines to make this work in Safari */
- // max-width: 100%;
- max-height: 100%;
- }
-
- }
-}
diff --git a/assets/event.less b/assets/event.less
deleted file mode 100644
index 2bf07805..00000000
--- a/assets/event.less
+++ /dev/null
@@ -1,56 +0,0 @@
-// .event {
-// width: 320px;
-// max-width: 450px;
-// flex-grow: 1;
-// margin: .2em;
-// background-color: #202020;
-// overflow: hidden;
-
-// a:hover {
-// text-decoration: none;
-// .title {
-// border-bottom: 1px solid #888;
-// color: white;
-// }
-// }
-
-// .title {
-// margin-left: 1rem;
-// margin-top: 1rem;
-// margin-right: 1rem;
-// border-bottom: 1px solid #333;
-// transition: border-color .5s;
-// font-size: 1.2em;
-// max-height: 3em;
-// overflow: hidden;
-// color: white;
-// font-weight: bold;
-// }
-
-// .card-footer {
-// max-height: 4.5em;
-// overflow: hidden;
-// padding: .25rem 0.5rem;
-// line-height: 1.8rem;
-// min-height: 2.2rem;
-// }
-
-// .card-body {
-// overflow: hidden;
-// }
-
-// .description {
-// color: #999;
-// font-size: 0.8em;
-// overflow: hidden;
-// max-height: 100%;
-// }
-
-// .el-image { width: 100% }
-// img {
-// width: 100%;
-// max-height: 250px;
-// object-fit: cover;
-// object-position: top;
-// }
-// }
diff --git a/assets/style.less b/assets/style.less
index 8d65d218..099d06d0 100644
--- a/assets/style.less
+++ b/assets/style.less
@@ -30,6 +30,10 @@ li {
justify-content: center;
}
+#calh {
+ height: 292px;
+}
+
.container {
max-width: 1400px;
}
@@ -91,7 +95,6 @@ li {
.place {
max-width: 100%;
span {
- display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
diff --git a/assets/variables.scss b/assets/variables.scss
new file mode 100644
index 00000000..253c9e3d
--- /dev/null
+++ b/assets/variables.scss
@@ -0,0 +1,8 @@
+// assets/variables.scss
+
+// Variables you want to modify
+// $btn-border-radius: 0px;
+
+// If you need to extend Vuetify SASS lists
+// $material-light: ( cards: blue );
+@import '~vuetify/src/styles/styles.sass';
\ No newline at end of file
diff --git a/components/Announcement.vue b/components/Announcement.vue
index 1eb45080..7074cf3c 100644
--- a/components/Announcement.vue
+++ b/components/Announcement.vue
@@ -1,15 +1,16 @@
nuxt-link(:to='`/announcement/${announcement.id}`')
- v-alert.mb-1(border='left' type='info' color="primary" show-icon) {{announcement.title}}
+ v-alert.mb-1(border='left' type='info' color="primary" :icon='mdiInformation') {{announcement.title}}
diff --git a/components/Calendar.vue b/components/Calendar.vue
index 327241ac..8426f0c0 100644
--- a/components/Calendar.vue
+++ b/components/Calendar.vue
@@ -1,17 +1,18 @@
#calendar
- vc-calendar(
+ vc-date-picker(
+ v-model='selectedDate'
title-position='left'
:is-dark="settings['theme.is_dark']"
:columns="$screens({ sm: 2 }, 1)"
+ @input='click'
@update:from-page='updatePage'
:locale='$i18n.locale'
:attributes='attributes'
transition='fade'
aria-label='Calendar'
is-expanded
- is-inline
- @dayclick='click')
+ is-inline)
```
-#### embed a single event
-> you can copy the code in **event page > Embed > Copy**
+### Embed a single event
+To embed an event in webpages you use `` custom element, you can copy the required code in **event's page > Embed > Copy**, should be like the following:
-
-
-```javascript
+```html
```
-#### embed event lists
-> you can copy the code in **Export > List > Copy**
-
-```javascript
-
-```
\ No newline at end of file
+
+
+
+
+### Embed event lists
+You can also embed a list of events using `` custom element, you can copy the required code in **Export > List > Copy**
+
+
+```html
+
+ Gancio Events
+
+```
+
+
+
+
+
+
+
+
+Gancio Events
+
+> info "Customize"
+> Note that you can modify the title (or completely remove it using an empty `title` param),
+> you can limit the list to a maximum number of events using the `maxlength` parameter and filter events by `tags` or `places` using that parameters (it's easier using **gancio** than to explain it here)
+
+
+## IFrame
+You can also use the old iframe method
+
+
+```html
+
+```
+
+
+## Wordpress
+To embed an event or a list of events into a [WordPress](https://wordpress.com) website you can use the [WPGancio](https://wordpress.org/plugins/wpgancio/) plugin, this allows you to use webcomponents and shortcodes and automatically includes the needed script in each page and post.
\ No newline at end of file
diff --git a/docs/index.md b/docs/index.md
index fcdab97e..159abe1d 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -18,22 +18,22 @@ A shared agenda for local communities.
## Some relevant key features:
- **Focus on content** not on people:
-nowhere on gancio appears the identity of who published the event, not even under a nickname, not even to administrators (except in the db). This is not an ego-friendly platform.
+nowhere on gancio does the identity of who posted an event appear, not even under a nickname, not even to administrators (except in the db). This is not an ego-friendly platform.
-- **Visitors first**. We do not want logged user to get more features than random visitor. We do not want users to register, except to publish events and even in this case you can publish an anonymous event.
+- **Visitors first**. We do not want logged user to get more features than random visitor. We don't want users to register, except to post events and even then you can post an anonymous event.
-- **Anonymous events**: optionally a visitor can create events without being registered (an administrator has to confirm them)
+- **Anonymous events**: optionally a visitor can create events without being registered (an administrator must confirm them)
-- **We are not interested in making hits** so we export events in many ways, via RSS feeds, via global or individual ics, incorporating lists of events or single event via iframe on other websites and via [AP]({% link federation.md %})
+- **We don't care about making hits** so we export events in many ways: via RSS feeds, via global or individual ics, allowing you to embed list of events or single event via [iframe or webcomponent]({% link embed.md %}) on other websites, via [AP]({% link federation.md %}), [microdata](https://developer.mozilla.org/en-US/docs/Web/HTML/Microdata) and [microformat](https://developer.mozilla.org/en-US/docs/Web/HTML/microformats#h-event)
- Very easy UI
-- Multidays events support (festival, conferences...)
-- Recurrent events support (each monday, each two monday, each monday and friday, each two saturday, etc.)
-- Filters events for tags or places
+- Multi-day events (festival, conferences...)
+- Recurring events (each monday, each two monday, each monday and friday, each two saturday, etc.)
+- Filter events for tags or places
- RSS and ICS export (with filters)
-- embeddable iframe ([example](https://gancio.cisti.org/embed/list?title=Upcoming events))
+- embed your events in your website with [webcomponents]({% link embed.md %}) or iframe ([example](https://gancio.cisti.org/embed/list?title=Upcoming events))
- boost / bookmark / comment events from the fediverse!
-- Lot of configurations available (user registration open/close, enable federation, enable recurrent events)
+- Lot of configurations available (dark/light theme, user registration open/close, enable federation, enable recurring events)
### License
diff --git a/docs/install/backup.md b/docs/install/backup.md
index 8b8f5e9d..169cf616 100644
--- a/docs/install/backup.md
+++ b/docs/install/backup.md
@@ -23,7 +23,7 @@ sudo -u postgres pg_dump -Fc gancio > gancio.dump
1. Archive database, configuration, custom user locales, logs, images and thumbnails
```bash
sudo tar -czf gancio-$(date +%Y-%m-%d-%H%M%S)-backup.tgz \
- $(ls -d config.json uploads user_locale db.sqlite gancio.dump postgres data logs 2> /dev/null)
+ $(ls -d config.json uploads user_locale db.sqlite gancio.dump postgres data db logs 2> /dev/null)
```
> info "Automatic backup"
diff --git a/docs/install/configuration.md b/docs/install/configuration.md
index 0f433ce2..6fcce96a 100644
--- a/docs/install/configuration.md
+++ b/docs/install/configuration.md
@@ -7,7 +7,7 @@ parent: Install
## Configuration
{: .no_toc }
-`gancio` configuration is done during installation process but you can change it editing the configuration file. Note that you can always re-run gancio with `--setup` flag to use the interactive setup.
+`gancio` configuration is done during installation process but you can change it editing the configuration file.
The configuration file shoud be a `.json` or a `.js` file and could be specified using the `--config` flag.
- eg. `gancio start --config ./config.json`
@@ -27,7 +27,7 @@ This probably support unix socket too
```
- ### Database
-DB configuration, look [here](https://sequelize.org/master/class/lib/sequelize.js~Sequelize.html#instance-constructor-constructor) for options.
+DB configuration, look [here](https://sequelize.org/v6/class/src/sequelize.js~Sequelize.html#instance-constructor-constructor) for options.
```json
"db": {
"dialect": "sqlite",
diff --git a/docs/install/debian.md b/docs/install/debian.md
index ee8c4048..5c69b5c2 100644
--- a/docs/install/debian.md
+++ b/docs/install/debian.md
@@ -21,8 +21,8 @@ sudo npm install -g yarn
```
[source](https://github.com/nodesource/distributions/blob/master/README.md)
-
-1. Setup with postgreSQL __(optional as you can choose sqlite)__
+#### Choose you database (sqlite, postgresql, mariadb, mysql)
+1. Setup using postgreSQL __(optional)__
```bash
sudo apt-get install postgresql
# Create the database
@@ -32,13 +32,25 @@ postgres=# create user gancio with encrypted password 'gancio';
postgres=# grant all privileges on database gancio to gancio;
```
+1. Setup using MariaDB (__optional__)
+```bash
+sudo apt-get install mariadb
+sudo mysql
+MariaDB [(none)]> create database gancio;
+Query OK, 1 row affected (0.001 sec)
+MariaDB [(none)]> create user gancio identified by 'gancio';
+Query OK, 0 rows affected (0.011 sec)
+MariaDB [(none)]> grant all privileges on gancio.* to gancio;
+Query OK, 0 rows affected (0.009 sec)
+```
+
1. Create a user to run gancio from
```bash
sudo adduser --group --system --shell /bin/false --home /opt/gancio gancio
```
1. Install Gancio
```bash
-sudo yarn global add --silent {{site.url}}/latest.tgz 2> /dev/null
+sudo yarn global add --silent {{site.url}}/latest.tgz
```
1. Setup systemd service and reload systemd
@@ -66,6 +78,6 @@ sudo systemctl start gancio
```bash
yarn global remove gancio
yarn cache clean
-yarn global add --silent {{site.url}}/latest.tgz 2> /dev/null
-sudo service gancio restart
+yarn global add --silent {{site.url}}/latest.tgz
+sudo systemctl restart gancio
```
diff --git a/docs/install/docker.md b/docs/install/docker.md
index 2acd4802..3a514a55 100644
--- a/docs/install/docker.md
+++ b/docs/install/docker.md
@@ -11,76 +11,51 @@ nav_order: 2
1. TOC
{:toc}
-## Initial setup
-
-
-- __You must have the following dependencies installed: Docker, Docker Compose and Nginx__
+## Setup
+Make sure to have [Docker Engine](https://docs.docker.com/engine/install/),
+[Docker Compose](https://docs.docker.com/compose/install/) and [nginx](https://nginx.org/en/docs/install.html) installed:
```bash
sudo apt install docker docker-compose nginx
```
-or
-1. [Install docker](https://docs.docker.com/engine/install/)
-1. [Install docker-compose](https://docs.docker.com/compose/install/)
-1. [Install nginx](https://nginx.org/en/docs/install.html)
-- __Create a directory where everything related to gancio is stored__
+Create a directory where everything related to gancio is stored:
```bash
mkdir -p /opt/gancio
cd /opt/gancio
```
-## Use sqlite
-
-
-1. **Download docker-compose.yml and Dockerfile**
+Download `Dockerfile` and `entrypoint.sh`:
```bash
wget {{site.url}}{% link /docker/Dockerfile %}
wget {{site.url}}{% link /docker/entrypoint.sh %}
-wget {{site.url}}{% link /docker/sqlite/docker-compose.yml %}
```
-
-1. Build docker image
-```
-docker-compose build
-```
-
-
-## Use postgreSQL
-
-
-1. **Download docker-compose.yml and Dockerfile**
+Download `docker-compose.yml` choosing your preferred database dialect between `sqlite`, `postgres` and `mariadb`:
```bash
-wget {{site.url}}{% link /docker/Dockerfile %}
-wget {{site.url}}{% link /docker/entrypoint.sh %}
-wget {{site.url}}{% link /docker/postgres/docker-compose.yml %}
+DB=sqlite
+wget {{site.url}}/docker/$DB/docker-compose.yml
```
-1. Build docker image
-```
+Build docker image
+```bash
docker-compose build
```
-
-
## Start gancio
-1. Run your container
+Start your container:
```bash
docker-compose up -d
```
-1. Look at logs
+You can take a look at logs using:
```bash
tail -f data/logs/gancio.log
```
-1. [Setup nginx as a proxy]({% link install/nginx.md %})
+You'll need to [setup nginx as a proxy]({% link install/nginx.md %}) then you can point your web browser to your domain :tada:
-1. Point your web browser to your domain :tada:
-
-1. Edit `data/config.json` and restart the container on your needs, see [Configuration]({% link install/configuration.md %}) for more details.
## Upgrade
@@ -89,20 +64,6 @@ tail -f data/logs/gancio.log
> Don't be lazy and [backup]({% link install/backup.md %}) your data!
-> error "Upgrade from a version < 1.0"
-> Since v1.0 our docker setup is changed and a new container has to be built:
->
-> 1. `cd /opt/gancio`
-> 1. [Backup your data]({% link install/backup.md %})
-> 1. Download new `Dockerfile` `wget {{site.url}}{% link /docker/Dockerfile %}`
-> 1. Download new `entrypoint.sh` `wget {{site.url}}{% link /docker/entrypoint.sh %}`
-> 1. Download new `docker-compose.yml` (substitute `sqlite` with `postgres` in case): `wget {{site.url}}{% link /docker/sqlite/docker-compose.yml %}`
-> 1. Build the new container `docker-compose build`
-> 1. Extract your backup into `./data` `mkdir data; tar xvzf gancio--backup.tgz -C data`
-> 1. Stop your old container `docker-compose stop`
-> 1. Start your new container `docker-compose up`
-
-
```bash
cd /opt/gancio
docker-compose up -d --no-deps --build
diff --git a/docs/install/install.md b/docs/install/install.md
index 817d6e7c..530f406c 100644
--- a/docs/install/install.md
+++ b/docs/install/install.md
@@ -9,7 +9,7 @@ has_toc: false
## Pre-requisites
- a Linux machine with root access (a VPS with 500MB of RAM and a cpu should be enough but do not use docker on a small machine :stuck_out_tongue_winking_eye:)
- a domain name or subdomain (eg. gancio.mydomain.org, subpath are not supported)
-- an SMTP server to deliver emails
+- optionally an SMTP server to deliver emails
## Install
diff --git a/docs/instances.md b/docs/instances.md
index 43cb5b28..056e9357 100644
--- a/docs/instances.md
+++ b/docs/instances.md
@@ -8,7 +8,10 @@ nav_order: 7
- [gancio.cisti.org](https://gancio.cisti.org) (Turin, Italy)
- [lapunta.org](https://lapunta.org) (Florence, Italy)
+- [sapratza.in](https://sapratza.in/) (Sardinia, Italy)
- [termine.161.social](https://termine.161.social) (Germany)
+- [ezkerraldea.euskaragendak.eus](https://ezkerraldea.euskaragendak.eus/)
+- [lakelogaztetxea.net](https://lakelogaztetxea.net)
Do you want your instance to appear here? [Write us]({% link contact.md %}).
diff --git a/docs/public.key b/docs/public.key
new file mode 100644
index 00000000..fd9f05b1
--- /dev/null
+++ b/docs/public.key
@@ -0,0 +1,83 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+/mmL8sP2wfO515ZBxq6+nuzOel+4IHFFqRFv
+=XDDO
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/layouts/error.vue b/layouts/error.vue
index c1bb7e29..25e0c6d9 100644
--- a/layouts/error.vue
+++ b/layouts/error.vue
@@ -1,16 +1,19 @@
v-container.p-4.text-center
- v-alert(v-if="error.statusCode === 404") ¯\_(ツ)_/¯ {{error.message}}
- v-alert(v-else type='error') mdi-warning An error occurred: {{error.message}}
+ v-alert(v-if="error.statusCode === 404" type='error' :icon='mdiAlert') ¯\_(ツ)_/¯ {{error.message}}
+ v-alert(v-else type='error' :icon='mdiAlert') An error occurred: {{error.message}}
nuxt-link(to='/')
v-btn Back to home