diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..1f1ea75221927d610d20f306f3be7a00bf6f588e --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +build/ +vendor/ + +composer.lock diff --git a/README.md b/README.md index b9f14c532813432cb63f82423668da0f1a5f193c..210ef49da9fe1190891f1d7a5d5ee9acf99543c6 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,85 @@ -# Secondary Mail -Place this app in **nextcloud/apps/** - -## Building the app - -The app can be built by using the provided Makefile by running: - - make - -This requires the following things to be present: -* make -* which -* tar: for building the archive -* curl: used if phpunit and composer are not installed to fetch them from the web -* npm: for building and testing everything JS, only required if a package.json is placed inside the **js/** folder - -The make command will install or update Composer dependencies if a composer.json is present and also **npm run build** if a package.json is present in the **js/** folder. The npm **build** script should use local paths for build systems and package managers, so people that simply want to build the app won't need to install npm libraries globally, e.g.: - -**package.json**: -```json -"scripts": { - "test": "node node_modules/gulp-cli/bin/gulp.js karma", - "prebuild": "npm install && node_modules/bower/bin/bower install && node_modules/bower/bin/bower update", - "build": "node node_modules/gulp-cli/bin/gulp.js" -} -``` - - -## Publish to App Store - -First get an account for the [App Store](http://apps.nextcloud.com/) then run: - - make && make appstore - -The archive is located in build/artifacts/appstore and can then be uploaded to the App Store. - -## Running tests -You can use the provided Makefile to run all tests by using: - - make test - -This will run the PHP unit and integration tests and if a package.json is present in the **js/** folder will execute **npm run test** - -Of course you can also install [PHPUnit](http://phpunit.de/getting-started.html) and use the configurations directly: - - phpunit -c phpunit.xml - -or: - - phpunit -c phpunit.integration.xml - -for integration tests +# Secondary Mail - Provide a secondary e-Mail Address to Nextcloud for third-party systems +Place this app in **nextcloud/apps/** (or install it from the Nextcloud app store), enable it and go to your profile page. + + +## About the plugin + +This app allows your NextCloud users to provide a secondary e-Mail in their profile pages and also specify, which address(es) should be used for communication by third-party systems (like mailinglists). This setting has no influence whatsoever on the mails sent out by Nextcloud, and Nextcloud also will not use the secondary e-mail address for notifications or password resets. + +However, external custom scripts can be used in combination with the user provisioning API to get the user's preferred e-mail address and use it to sync e.g. Mailman Mailinglists with the nextcloud users. One use case is when nextcloud is used for professional associations, where all users have a work e-mail and private e-mail addresses. Typically, the work address will be used as the primary, but some users prefer to get a copy of all mails/announcements also to their secondary e-mail. + +The primary e-mail address in the nextcloud profile will always be used for nextcloud's notifications and password resets. + +This app on its own is not very useful, its full power can only be enjoyed in combination with custom scripts using the user provisioning API (OCS) endpoints to extract the preferred e-mail addresses to third-party systems. + +## Editing the secondary email and the preferences in the profile + + + +## Using OCS endpoints (user provisioning API) to extract email preferences to third-party systems + +The app provides two OCS endpoints that allow scripts to extract the user's preferred e-mail from nextcloud: + + * /ocs/v1.php/apps/secondarymail/getAddress/[USERID] - (GET) + * /ocs/v1.php/apps/secondarymail/settings/[USERID] - (PUT with parameters key=(email2|emailUsePrimary|emailUseSecondary) and value=...) + +### Querying for the list of preferred e-mails for communication + +This call needs to provide a username and password that has the permissions to read user's profile data, typically this means members of the admin group: + + curl -u [USERNAME]:[PASSWORD] -X GET \ + "https://[SERVERURL]/ocs/v1.php/apps/secondarymail/getAddress/[USERID]" \ + -H "OCS-APIRequest: true" + +Response: +``` +<?xml version="1.0"?> +<ocs> + <meta> + <status>ok</status> + <statuscode>100</statuscode> + <message>OK</message> + <totalitems></totalitems> + <itemsperpage></itemsperpage> + </meta> + <data> + <usePrimary>true</usePrimary> + <useSecondary>true</useSecondary> + <email> + <element>test@demo.open-tools.net</element> + <element>secondary@dem.open-tools.net</element> + </email> + </data> +</ocs> +``` + +### Setting the secondary e-mail address or changing preferred flags + +The /ocs/v1.php/apps/secondarymail/settings/[USERID] endpoint expects two parameters: + * `key`: either email2, emailUsePrimary or emailUseSecondary) + * `value`: The email-address if key=="email2", or "true"/"false" for the preferences + + curl -u [USERNAME]:[PASSWORD] -X POST \ + "https://[SERVERURL]/ocs/v1.php/apps/secondarymail/settings/[USERID]?key=email2&value=[SECONDARY-MAIL]"\ + -H "OCS-APIRequest: true" + +Response: +``` +<?xml version="1.0"?> +<ocs> + <meta> + <status>ok</status> + <statuscode>100</statuscode> + <message>OK</message> + <totalitems></totalitems> + <itemsperpage></itemsperpage> + </meta> + <data> + <user>test</user> + <key>email2</key> + <value>secondary@demo.open-tools.net</value> + <action>changed</action> + <success>1</success> + </data> +</ocs> +``` diff --git a/appinfo/routes.php b/appinfo/routes.php index 334729d122f4ddcad0eaeb7e07e19b3a697522c6..1bdd0e4d91daaf6c4bcb2af365f6b9b2b4e5361d 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -15,5 +15,6 @@ return [ 'ocs' => [ ['name' => 'SecondaryMail#getAddress', 'url' => '/getAddress/{id}', 'verb' => 'GET'], ['name' => 'SecondaryMail#setProperty', 'url' => '/settings', 'verb' => 'POST'], + ['name' => 'SecondaryMail#setPropertyForUser', 'url' => '/settings/{id}', 'verb' => 'POST'], ] ]; diff --git a/img/Nextcloud_SecondaryMail_Profile.png b/img/Nextcloud_SecondaryMail_Profile.png new file mode 100644 index 0000000000000000000000000000000000000000..4a512cd9c099a8a40ea580a6cb8468b0966faa53 Binary files /dev/null and b/img/Nextcloud_SecondaryMail_Profile.png differ diff --git a/img/Nextcloud_SecondaryMail_ProfileCloseup.png b/img/Nextcloud_SecondaryMail_ProfileCloseup.png new file mode 100644 index 0000000000000000000000000000000000000000..79b88c9dcd97120aa9ddfb7f6728ed334abe9386 Binary files /dev/null and b/img/Nextcloud_SecondaryMail_ProfileCloseup.png differ diff --git a/lib/Controller/SecondaryMailController.php b/lib/Controller/SecondaryMailController.php index 88f7e9de469ae75bfe7d4eca0490852bf2c5e4a7..1cc8c653be8355d2f6b59cac390bde232920d006 100644 --- a/lib/Controller/SecondaryMailController.php +++ b/lib/Controller/SecondaryMailController.php @@ -53,14 +53,33 @@ class SecondaryMailController extends OCSController { * @PasswordConfirmationRequired */ public function setProperty($key, $value) { + return $this->setPropertyForUser($this->user, $key, $value); + } + + /** + * @NoAdminRequired + * @PasswordConfirmationRequired + */ + public function setPropertyForUser($id, $key, $value) { + $data = array(); + $data['user'] = $id; + $data['key'] = $key; + $data['value'] = $value; if (in_array($key, array('emailUsePrimary', 'emailUseSecondary', 'email2'))) { if ($key === 'email2' && $value === "") { - $this->config->deleteUserValue($this->user, 'settings', $key); + $this->config->deleteUserValue($id, 'settings', $key); + $data['action'] = "deleted"; } else { - $this->config->setUserValue($this->user, 'settings', $key, $value); + $this->config->setUserValue($id, 'settings', $key, $value); + $data['action'] = "changed"; } + $data['success'] = true; + return new DataResponse($data); + } else { + $data['action'] = "UNKNOWN KEY"; + $data['success'] = false; + return new DataResponse($data); } - return new DataResponse(true); } /** diff --git a/lib/Settings/Personal.php b/lib/Settings/Personal.php index 09d475146e47e5f7a1f2604599f20f8ee426a779..5942c6006a6b6b855a208b89b77905afb5ec7487 100644 --- a/lib/Settings/Personal.php +++ b/lib/Settings/Personal.php @@ -50,9 +50,9 @@ class Personal implements ISettings { */ public function getForm() { $parameters = [ - 'use_primary_mail' => $this->config->getUserValue($this->user, 'settings', 'emailUsePrimary', 1), - 'use_secondary_mail' => $this->config->getUserValue($this->user, 'settings', 'emailUseSecondary', 0), - 'secondaryMail' => $this->config->getUserValue($this->user, 'settings', 'email2', 'office@open-tools.net'), + 'use_primary_mail' => $this->config->getUserValue($this->user, 'settings', 'emailUsePrimary', 'true'), + 'use_secondary_mail' => $this->config->getUserValue($this->user, 'settings', 'emailUseSecondary', 'true'), + 'secondaryMail' => $this->config->getUserValue($this->user, 'settings', 'email2', ''), 'userid' => $this->user ]; return new TemplateResponse('secondarymail', 'settings/personal', $parameters);