diff --git a/.docker/README.md b/.docker/README.md new file mode 100644 index 0000000..37b52ab --- /dev/null +++ b/.docker/README.md @@ -0,0 +1,62 @@ +# Docker development environment + +The docker development environment can be easilly instanciated by running the `docker compose up -d` command +from the project root directory. +The container will be name `plugins.glpi-project.org` and you can access its terminal by running the +`docker exec --interactive --tty plugins.glpi-project.org bash` command. + +## Custom configuration + +You can customize the docker services by creating a `docker-compose.override.yaml` file in the project root directory. + +## HTTP server + +By default, the Apache HTTP port is published on the `8080` port, the Node HTTP server is published on the `9000` port +and the live server on the `35729` port. +You can change them in the `docker-compose.override.yaml` file. + +```yaml +services: + app: + ports: !override + - "8000:80" + - "8001:9000" + - "8002:35729" +``` + +The default uid/gid used by the docker container is `1000`. If your host user uses different uid/gid, you may encounter +file permissions issues. To prevent this, you can customize them using the corresponding build args in +the `docker-compose.override.yaml` file. + +```yaml +services: + app: + build: + args: + HOST_GROUP_ID: "1001" + HOST_USER_ID: "1001" +``` + +### Database server + +By default, the database service is not provided. You can add it in the `docker-compose.override.yaml` file. + +```yaml +services: + database: + container_name: "db" + image: "mariadb:11.0" + restart: "unless-stopped" + environment: + MYSQL_ROOT_PASSWORD: "R00tP4ssw0rd" + MYSQL_DATABASE: "plugins" + MYSQL_USER: "plugins" + MYSQL_PASSWORD: "P4ssw0rd" + ports: + - "3306:3306" + volumes: + - "db:/var/lib/mysql" + +volumes: + db: +``` diff --git a/.docker/development/Dockerfile b/.docker/development/Dockerfile index 8fb914b..381cb72 100644 --- a/.docker/development/Dockerfile +++ b/.docker/development/Dockerfile @@ -1,6 +1,6 @@ -FROM composer:latest AS composer +FROM composer:1 AS composer -FROM php:7.4-apache +FROM php:7.4-apache-bullseye # Workaround to make apache use same UID/GID as host user. ARG HOST_GROUP_ID=1000 @@ -22,13 +22,10 @@ RUN apt-get update \ # Install PDO MySQL PHP extension. && docker-php-ext-install pdo pdo_mysql \ \ - # Install cron service. - && apt-get install --assume-yes --no-install-recommends --quiet cron \ - \ # Install nodejs, npm and build utils. - && apt-get install --assume-yes --no-install-recommends --quiet gnupg \ - && curl --silent --location https://deb.nodesource.com/setup_10.x | bash - \ - && apt-get install --assume-yes --no-install-recommends --quiet nodejs \ + && mkdir /opt/nodejs && curl --silent --location https://nodejs.org/download/release/v10.24.1/node-v10.24.1-linux-x64.tar.gz | tar --extract --gzip --strip-components=1 --verbose --directory=/opt/nodejs \ + && ln --symbolic /opt/nodejs/bin/node /usr/bin/node \ + && ln --symbolic /opt/nodejs/bin/npm /usr/bin/npm \ && npm install -g bower grunt \ && apt-get install --assume-yes --no-install-recommends --quiet ruby-dev \ && gem install compass \ @@ -43,6 +40,9 @@ RUN apt-get update \ # Clean sources list && rm -rf /var/lib/apt/lists/* +# Add global node installed libs to path +ENV PATH="/opt/nodejs/bin/:${PATH}" + # Required for PhantomJS. ENV OPENSSL_CONF=/etc/ssl/ @@ -51,16 +51,6 @@ COPY --from=composer /usr/bin/composer /usr/bin/composer # Copy files to container. COPY ./files/etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/000-default.conf -COPY ./files/opt/startup.sh /opt/startup.sh -COPY ./files/etc/cron.d/plugins.glpi-project.org /etc/cron.d/plugins.glpi-project.org -# Install crontab. -RUN crontab -u www-data /etc/cron.d/plugins.glpi-project.org - -# Define application path as volume and working dir -VOLUME /var/www/plugins.glpi-project.org +USER www-data WORKDIR /var/www/plugins.glpi-project.org - -# Make startup script executable and executes it as default command. -RUN chmod u+x /opt/startup.sh -CMD /opt/startup.sh diff --git a/.docker/development/docker-compose.yml b/.docker/development/docker-compose.yml deleted file mode 100644 index a055470..0000000 --- a/.docker/development/docker-compose.yml +++ /dev/null @@ -1,21 +0,0 @@ -version: "3.5" - -services: - plugins.glpi-project.org: - container_name: "${CONTAINER_NAME:-plugins.glpi-project.org}" - restart: "${CONTAINER_RESTART_POLICY:-unless-stopped}" - build: - context: "." - args: - HOST_GROUP_ID: "${HOST_GROUP_ID:-1000}" - HOST_USER_ID: "${HOST_USER_ID:-1000}" - ports: - - "${HTTP_PORT_APACHE:-8000}:80" - - "${HTTP_PORT_NODEJS:-9000}:9000" - - "${HTTP_PORT_LIVERELOAD:-35729}:35729" - volumes: - - type: "bind" - source: "../.." - target: "/var/www/plugins.glpi-project.org" - extra_hosts: - - "host.docker.internal:host-gateway" diff --git a/.docker/development/files/etc/cron.d/plugins.glpi-project.org b/.docker/development/files/etc/cron.d/plugins.glpi-project.org deleted file mode 100644 index 60d9d58..0000000 --- a/.docker/development/files/etc/cron.d/plugins.glpi-project.org +++ /dev/null @@ -1 +0,0 @@ -*/5 * * * * /usr/local/bin/php /var/www/plugins.glpi-project.org/misc/run_tasks.php &>/dev/null diff --git a/.docker/development/files/opt/startup.sh b/.docker/development/files/opt/startup.sh deleted file mode 100644 index 656cefb..0000000 --- a/.docker/development/files/opt/startup.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -# Run cron service. -cron - -# Run command previously defined in base php-apache Dockerfile. -apache2-foreground diff --git a/.gitignore b/.gitignore index a17a2ae..de8d2fa 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ api/config.php /frontend/app/scripts/conf.js /misc/illuminate_queries.log .vagrant +/docker-compose.override.yaml diff --git a/api/src/core/BackgroundTasks.php b/api/src/core/BackgroundTasks.php index dfe194e..b32d6ad 100644 --- a/api/src/core/BackgroundTasks.php +++ b/api/src/core/BackgroundTasks.php @@ -359,6 +359,7 @@ private function updatePlugin($plugin, $index = null, $length = null, $subtasks) $plugin->download_url = $this->sanitizeUrl($xml->download); $plugin->issues_url = $this->sanitizeUrl($xml->issues); $plugin->readme_url = $this->sanitizeUrl($xml->readme); + $plugin->changelog_url = isset($xml->changelog) ? $this->sanitizeUrl($xml->changelog) : null; $plugin->license = $this->sanitizeText($xml->license); // reading descriptions, diff --git a/api/src/core/ValidableXMLPluginDescription.php b/api/src/core/ValidableXMLPluginDescription.php index 7a4b5d7..b89e6ff 100644 --- a/api/src/core/ValidableXMLPluginDescription.php +++ b/api/src/core/ValidableXMLPluginDescription.php @@ -91,6 +91,14 @@ public function validateHomepage() { return true; } + public function validateChangeLog() { + if (sizeof($this->contents->changelog) != 1 || + sizeof($this->contents->changelog->children()) != 0) { + $this->throwOrCollect(new InvalidXML('field', 'changelog', ' should be a singular field without children')); + } + return true; + } + public function validateDownload() { if (sizeof($this->contents->download) != 1 || sizeof($this->contents->download->children()) != 0) { diff --git a/api/src/models/Plugin.php b/api/src/models/Plugin.php index da7d06a..6080256 100644 --- a/api/src/models/Plugin.php +++ b/api/src/models/Plugin.php @@ -64,7 +64,7 @@ public function scopeShort($query) { 'plugin.xml_url', 'plugin.homepage_url', 'plugin.download_url', 'plugin.issues_url', 'plugin.readme_url', 'plugin.license', 'plugin.date_added', 'plugin.date_updated', - 'plugin.download_count', 'plugin.xml_state']); + 'plugin.download_count', 'plugin.xml_state', 'plugin.changelog_url']); return $query; } diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..7fc8ff0 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,13 @@ +services: + app: + container_name: "plugins.glpi-project.org" + build: + context: ".docker/development" + ports: + - "8080:80" + - "9000:9000" + - "35729:35729" + volumes: + - ".:/var/www/plugins.glpi-project.org:rw" + extra_hosts: + - "host.docker.internal:host-gateway" diff --git a/frontend/app/scripts/translations/cs.js b/frontend/app/scripts/translations/cs.js index 9968bbf..6536c45 100644 --- a/frontend/app/scripts/translations/cs.js +++ b/frontend/app/scripts/translations/cs.js @@ -245,6 +245,7 @@ angular FORGOTPASSWORD_DIALOG_FORMINTRO_1: "Pokud jste zde, nejspíš jste ztratili své heslo.", FORGOTPASSWORD_DIALOG_FORMINTRO_2: "Je třeba, abyste zadali e-mail svého účtu.", FORGOTPASSWORD_DIALOG_FORMINTRO_3: "Mějte na paměti, že pokud jste předtím ještě nikdy nenastavovali heslo (protože jste se vždy přihlašovali prostřednictvím Github) pak není možné heslo obnovit, protože nikdy nebylo nastavené. Měli byste tento dialog zavřít a ověřit se prostřednictvím Github.", - SEND_MAIL_PASSWORD_RESET_LINK: "Poslat odkaz na resetování hesla e-mailem" + SEND_MAIL_PASSWORD_RESET_LINK: "Poslat odkaz na resetování hesla e-mailem", + CHANGELOG: 'Changelog', }); }); diff --git a/frontend/app/scripts/translations/en.js b/frontend/app/scripts/translations/en.js index 11776a6..876fb41 100644 --- a/frontend/app/scripts/translations/en.js +++ b/frontend/app/scripts/translations/en.js @@ -245,6 +245,7 @@ angular FORGOTPASSWORD_DIALOG_FORMINTRO_1: "If you're here, it's probably because you lost your password.", FORGOTPASSWORD_DIALOG_FORMINTRO_2: "We need you to provide your account's email.", FORGOTPASSWORD_DIALOG_FORMINTRO_3: "Please mind that if you've never setup a password before (because you always logged-in with Github) then it's not possible to recover the password because as said, you never set any. You should close this dialog and auth with Github.", - SEND_MAIL_PASSWORD_RESET_LINK: "Send password reset link via mail" + SEND_MAIL_PASSWORD_RESET_LINK: "Send password reset link via mail", + CHANGELOG: 'Changelog', }); }); diff --git a/frontend/app/scripts/translations/es.js b/frontend/app/scripts/translations/es.js index c9037d8..931a57d 100644 --- a/frontend/app/scripts/translations/es.js +++ b/frontend/app/scripts/translations/es.js @@ -245,6 +245,7 @@ angular FORGOTPASSWORD_DIALOG_FORMINTRO_1: "If you're here, it's probably because you lost your password.", FORGOTPASSWORD_DIALOG_FORMINTRO_2: "We need you to provide your account's email.", FORGOTPASSWORD_DIALOG_FORMINTRO_3: "Please mind that if you've never setup a password before (because you always logged-in with Github) then it's not possible to recover the password because as said, you never set any. You should close this dialog and auth with Github.", - SEND_MAIL_PASSWORD_RESET_LINK: "Send password reset link via mail" + SEND_MAIL_PASSWORD_RESET_LINK: "Send password reset link via mail", + CHANGELOG: 'Changelog', }); }); \ No newline at end of file diff --git a/frontend/app/scripts/translations/fr.js b/frontend/app/scripts/translations/fr.js index 2749204..91cec9a 100644 --- a/frontend/app/scripts/translations/fr.js +++ b/frontend/app/scripts/translations/fr.js @@ -245,6 +245,7 @@ angular FORGOTPASSWORD_DIALOG_FORMINTRO_1: "Si vous êtes ici c'est sûrement parce que vous avez oublié votre mot de passe.", FORGOTPASSWORD_DIALOG_FORMINTRO_2: "Nous avons besoin de l'adresse e-mail de votre compte utilisateur", FORGOTPASSWORD_DIALOG_FORMINTRO_3: "Veuillez noter que si vous n'avez jamais défini de mot de passe (parce que vous vous connectiez via GitHub) il nous est impossible de le ré-initialiser puisque, comme évoqué, vous n'en avez jamais défini. Vous devriez fermer cette fenêtre et vous identifier avec GitHub.", - SEND_MAIL_PASSWORD_RESET_LINK: "Envoyer le lien de ré-initialisation par e-mail" + SEND_MAIL_PASSWORD_RESET_LINK: "Envoyer le lien de ré-initialisation par e-mail", + CHANGELOG: 'Notes de version', }); }); diff --git a/frontend/app/scripts/translations/hr.js b/frontend/app/scripts/translations/hr.js index 7f83ab9..e47ec9c 100644 --- a/frontend/app/scripts/translations/hr.js +++ b/frontend/app/scripts/translations/hr.js @@ -245,6 +245,7 @@ angular FORGOTPASSWORD_DIALOG_FORMINTRO_1: "Ako se nalaziš ovdje, vjerojatno se radi o tome da si zaboravio/la lozinku.", FORGOTPASSWORD_DIALOG_FORMINTRO_2: "Moraš navesti tvoju e-mail adresu računa.", FORGOTPASSWORD_DIALOG_FORMINTRO_3: "Ako nikada prije nisi postavio/la lozinku (jer si se uvijek prijavio/la s Github računom), onda nije moguće obnoviti lozinku jer, kao što je rečeno, nikada je nisi postavio/la. Zatvori ovaj dijalog i autentificiraj se s Github računom.", - SEND_MAIL_PASSWORD_RESET_LINK: "Pošalji poveznicu za resetiranje lozinke putem e-maila" + SEND_MAIL_PASSWORD_RESET_LINK: "Pošalji poveznicu za resetiranje lozinke putem e-maila", + CHANGELOG: 'Dnevnik promjena', }); }); diff --git a/frontend/app/views/plugin.html b/frontend/app/views/plugin.html index 9160326..ff26ee6 100644 --- a/frontend/app/views/plugin.html +++ b/frontend/app/views/plugin.html @@ -99,6 +99,12 @@

{{plugin.issues_url}} +
  • + + + {{plugin.changelog_url}} + +
  • {{fromNow(plugin.date_added)}} diff --git a/frontend/app/views/submit.html b/frontend/app/views/submit.html index 17ebd25..3ac50a3 100644 --- a/frontend/app/views/submit.html +++ b/frontend/app/views/submit.html @@ -40,6 +40,7 @@

    http://link/to/your/files http://link/to/your/issues http://link/to/your/readme + http://link/to/your/changelog Your name diff --git a/misc/init-db.sql b/misc/init-db.sql index 915f1b9..d4d01a1 100644 --- a/misc/init-db.sql +++ b/misc/init-db.sql @@ -75,6 +75,7 @@ CREATE TABLE `plugin` ( `download_url` text, `issues_url` text, `readme_url` text, + `changelog_url` text, `license` varchar(255) DEFAULT NULL, `date_added` date DEFAULT NULL, `date_updated` date DEFAULT NULL,