mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-11 00:14:50 +03:00
Added NextCloud
Taken from https://github.com/pierre-alain-b/snappymail-nextcloud
This commit is contained in:
parent
2dde6c59eb
commit
65200af210
32 changed files with 1713 additions and 1 deletions
17
integrations/nextcloud/snappymail/INSTALL
Executable file
17
integrations/nextcloud/snappymail/INSTALL
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
************************************************************************
|
||||
*
|
||||
* Nextcloud - SnappyMail Webmail package
|
||||
*
|
||||
* @author SnappyMail Team, Nextgen-Networks (@nextgen-networks), Tab Fitts (@tabp0le), Pierre-Alain Bandinelli (@pierre-alain-b)
|
||||
*
|
||||
************************************************************************
|
||||
|
||||
REQUIREMENTS:
|
||||
- Nextcloud version 14 and above
|
||||
|
||||
INSTALL & CONFIGURATION:
|
||||
Start within Nextcloud, and click on the "+ Apps" button in the upper-left corner dropdown menu:
|
||||
Then, enable the SnappyMail plugin that is in the "Social & communication" section.
|
||||
After a quick wait, SnappyMail is installed. Even if it is really attractive, it is too soon to click on the newly appeared "Email" icon in the apps list. You should configure SnappyMail before using it (which makes some sense, doesn'it): go to Nextcloud admin panel (upper-right corner dropdown menu) and go to "Additionnal settings". There click on the "Go to SnappyMail Webmail admin panel".
|
||||
In the SnappyMail admin prompt, the default login is "admin" and the default password is "12345". No need to advise you to change it once in the admin panel!
|
||||
This is it, you are now free to configure SnappyMail as you wish. One important point is the Domains section when you will set up the IMAP/SMTP parameters that shall be associated with the email adresses of your users.
|
||||
76
integrations/nextcloud/snappymail/README.md
Normal file
76
integrations/nextcloud/snappymail/README.md
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
# snappymail-nextcloud
|
||||
|
||||
snappymail-nextcloud is a plugin for Nextcloud to use the excellent SnappyMail webmail (https://snappymail.eu/).
|
||||
|
||||
## Which branch for which version of Nextcloud?
|
||||
|
||||
- The master branch corresponds to the latest stable version of the plugin that is suitable for Nextcloud 19 and upwards.
|
||||
- The 'up-to-nc18' corresponds to the working version of the plugin for Nextcloud 14 to 18.
|
||||
- The 'nc14' branch corresponds to a beta version of the plugin for Nextcloud 14. All the changes of 'nc14' branch were merged into master when it was deemed suitable for production.
|
||||
- The 'nc13' branch corresponds to the working version of the plugin for Nextcloud 10 to Nextcloud 13.
|
||||
|
||||
|
||||
Thank you to all contributors to SnappyMail for nextcloud:
|
||||
- SnappyMail Team, who initiated it
|
||||
- Tab Fitts (@tabp0le)
|
||||
- Nextgen Networks (@nextgen-networks)
|
||||
|
||||
## How to Install
|
||||
|
||||
Start within Nextcloud, and click on the "+ Apps" button in the upper-left corner dropdown menu:
|
||||
|
||||

|
||||
|
||||
Then, enable the SnappyMail plugin that you will find in the "Social & communication" section:
|
||||
|
||||

|
||||
|
||||
After a quick wait, SnappyMail is installed. Now you should configure it before use: open the Nextcloud admin panel (upper-right corner dropdown menu) and go to "Additionnal settings". There, click on the "Go to SnappyMail Webmail admin panel" link.
|
||||
|
||||

|
||||
|
||||
To enter SnappyMail admin area, the default login is "admin" and the default password is "12345". Don't forget to change it once in the admin panel!
|
||||
|
||||
From that point, all instance-wide SnappyMail settings can be tweaked as you wish. One important point is the "Domains" section where you should set up the IMAP/SMTP parameters that will be associated with the email adresses of your users. Basically, if a user of the Nextcloud instance starts SnappyMail and puts "firstname@domain.tld" as an email address, then SnappyMail should know how to connect to the IMAP & SMTP of domain.tld. You can fill in this information in the "Domains" section of the SnappyMail admin settings.
|
||||
|
||||

|
||||
|
||||
## SnappyMail Settings, Where Are They?
|
||||
|
||||
SnappyMail for Nextcloud is highly configurable. But settings are available in multiple places and this can be misleading for first-time users.
|
||||
|
||||
### SnappyMail admin settings
|
||||
SnappyMail admin settings can be reached only by the Nextcloud administrator. Open the Nextcloud admin panel ("Admin" in the upper-right corner dropdown menu) and go to "Additionnal settings". There, click on the "Go to SnappyMail Webmail admin panel" link. Alternatively, you may use the following link: https://path.to.nextcloud/index.php/apps/snappymail/app/?admin.
|
||||
|
||||
SnappyMail admin settings include all settings that will apply to all SnappyMail users (default login rules, branding, management of plugins, security rules and domains).
|
||||
|
||||
### SnappyMail user settings
|
||||
Each user of SnappyMail can also change user-specific behaviors in the SnappyMail user settings. SnappyMail user settings are found within SnappyMail by clicking on the user button (in the upper-right corner of SnappyMail) and then choosing "Settings" in the dropdown menu.
|
||||
|
||||
SnappyMail user settings include management of contacts, of email accounts, of folders, appearance and OpenPGP.
|
||||
|
||||
### The specificity of SnappyMail user accounts
|
||||
The plugin passes the login information of the user to the SnappyMail app which then creates and manages the user accounts. Accounts in SnappyMail are based soley on the authenticated email accounts, and do not take into account the nextcloud user which created them in the first place. If two or more Nextcloud users have the same email account in additional settings, they will in fact share the same 'email account' in SnappyMail including any additional email accounts that they may have added subsequently to their main account.
|
||||
This is to be kept in mind for the use case where multiple users shall have the same email account but may be also tempted to add additionnal acounts to their SnappyMail.
|
||||
|
||||
## How to auto-connect to SnappyMail?
|
||||
|
||||
### Auto-connection for all Nextcloud users
|
||||
If your Nextcloud users base is synchronized with an email system, then it is possible that Nextcloud credentials could be used right away to access the centralized email system. In the SnappyMail admin settings, the Nextcloud administrator can then tick the "Automatically login with Nextcloud/Nextcloud user credentials" checkbox.
|
||||
|
||||
Beware, if you tick this box, all Nextcloud users will *not* be able to use the override it with the setting below.
|
||||
|
||||
### Auto-connection for one user at a time
|
||||
Except if the above setting is activated, any Nextcloud user can have Nextcloud and SnappyMail keep in mind the default email/password to connect to SnappyMail. There, logging in Nextcloud is sufficient to then access SnappyMail within Nextcloud.
|
||||
|
||||
To fill in the default email address and password to use, each Nextcloud user should go in the personal settings: choose "Personal" in the upper-right corner dropdown menu. Then select the "Rainlopp webmail" section. You can also use this direct link: https://path.to.nextcloud/index.php/settings/personal#snappymail-webmail.
|
||||
|
||||
|
||||
## How to Activate SnappyMail Logging and then Find Logs
|
||||
|
||||
You can activate SnappyMail logging here: `/path/to/nextcloud/data/snappymail-storage/_data_/_default_/configs/application.ini`
|
||||
```
|
||||
[logs]
|
||||
enable = On
|
||||
```
|
||||
Logs are then available in `/path/to/nextcloud/data/snappymail-storage/_data_/_default_/logs/`
|
||||
1
integrations/nextcloud/snappymail/VERSION
Executable file
1
integrations/nextcloud/snappymail/VERSION
Executable file
|
|
@ -0,0 +1 @@
|
|||
2.5.3
|
||||
15
integrations/nextcloud/snappymail/appinfo/app.php
Normal file
15
integrations/nextcloud/snappymail/appinfo/app.php
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Nextcloud - SnappyMail mail plugin
|
||||
*
|
||||
* @author SnappyMail Team, Nextgen-Networks (@nextgen-networks), Tab Fitts (@tabp0le), Pierre-Alain Bandinelli (@pierre-alain-b)
|
||||
*
|
||||
* Based initially on https://github.com/SnappyMail/snappymail-webmail/tree/master/build/owncloud
|
||||
*/
|
||||
|
||||
$app = new OCA\SnappyMail\AppInfo\Application();
|
||||
$app->registerNavigation();
|
||||
$app->registerPersonalSettings();
|
||||
$app->getContainer()->query('SnappyMailHelper')->registerHooks();
|
||||
|
||||
30
integrations/nextcloud/snappymail/appinfo/info.xml
Normal file
30
integrations/nextcloud/snappymail/appinfo/info.xml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0"?>
|
||||
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
|
||||
<id>snappymail</id>
|
||||
<name>SnappyMail</name>
|
||||
<summary>SnappyMail Webmail</summary>
|
||||
<description>Simple, modern and fast web-based email client. After enabling in Nextcloud, go to Nextcloud admin panel, "Additionnal settings" and you will see a "SnappyMail webmail" section. There, click on the link to go to the SnappyMail admin panel. The default user/password is admin/12345. This version is based on SnappyMail 2.5.3 (2021-07).</description>
|
||||
<version>2.5.3</version>
|
||||
<licence>agpl</licence>
|
||||
<author>SnappyMail Team, Nextgen-Networks, Tab Fitts, Nathan Kinkade, Pierre-Alain Bandinelli</author>
|
||||
<namespace>SnappyMail</namespace>
|
||||
<documentation>
|
||||
<user>https://github.com/pierre-alain-b/snappymail-nextcloud/blob/master/README.md</user>
|
||||
<website>https://snappymail.eu/</website>
|
||||
</documentation>
|
||||
<category>social</category>
|
||||
<category>tools</category>
|
||||
<category>integration</category>
|
||||
<screenshot>https://raw.githubusercontent.com/pierre-alain-b/snappymail-nextcloud/master/screenshots/2016.10.20-screenshot.jpg</screenshot>
|
||||
<website>https://github.com/pierre-alain-b/snappymail-nextcloud</website>
|
||||
<bugs>https://github.com/pierre-alain-b/snappymail-nextcloud/issues</bugs>
|
||||
<screenshot>https://raw.githubusercontent.com/pierre-alain-b/snappymail-nextcloud/master/screenshots/2016.10.20-screenshot.jpg</screenshot>
|
||||
<dependencies>
|
||||
<php min-version="7.4" />
|
||||
<owncloud min-version="6" max-version="9.2" />
|
||||
<nextcloud min-version="20" max-version="22" />
|
||||
</dependencies>
|
||||
<settings>
|
||||
<admin>OCA\SnappyMail\Settings\AdminSettings</admin>
|
||||
</settings>
|
||||
</info>
|
||||
31
integrations/nextcloud/snappymail/appinfo/routes.php
Executable file
31
integrations/nextcloud/snappymail/appinfo/routes.php
Executable file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'routes' => [
|
||||
[
|
||||
'name' => 'page#index',
|
||||
'url' => '/',
|
||||
'verb' => 'GET'
|
||||
],
|
||||
[
|
||||
'name' => 'page#appGet',
|
||||
'url' => '/app/',
|
||||
'verb' => 'GET'
|
||||
],
|
||||
[
|
||||
'name' => 'page#appPost',
|
||||
'url' => '/app/',
|
||||
'verb' => 'POST'
|
||||
],
|
||||
[
|
||||
'name' => 'ajax#setPersonal',
|
||||
'url' => '/ajax/personal.php',
|
||||
'verb' => 'POST'
|
||||
],
|
||||
[
|
||||
'name' => 'ajax#setAdmin',
|
||||
'url' => '/ajax/admin.php',
|
||||
'verb' => 'POST'
|
||||
]
|
||||
]
|
||||
];
|
||||
1
integrations/nextcloud/snappymail/appinfo/version
Executable file
1
integrations/nextcloud/snappymail/appinfo/version
Executable file
|
|
@ -0,0 +1 @@
|
|||
7.1.2
|
||||
6
integrations/nextcloud/snappymail/css/style.css
Executable file
6
integrations/nextcloud/snappymail/css/style.css
Executable file
|
|
@ -0,0 +1,6 @@
|
|||
/*
|
||||
Empty style sheet!
|
||||
Only needed to give you the opportunity to theme the owncloud part
|
||||
of the snappymail app with the theming system integrated in ownCoud
|
||||
if the snappymail app is activated.
|
||||
*/
|
||||
BIN
integrations/nextcloud/snappymail/img/favicon.png
Normal file
BIN
integrations/nextcloud/snappymail/img/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 832 B |
BIN
integrations/nextcloud/snappymail/img/logo-64x64.png
Executable file
BIN
integrations/nextcloud/snappymail/img/logo-64x64.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 832 B |
265
integrations/nextcloud/snappymail/img/rainloop.svg
Normal file
265
integrations/nextcloud/snappymail/img/rainloop.svg
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="svg833"
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
sodipodi:docname="rainloop.svg"
|
||||
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
|
||||
<metadata
|
||||
id="metadata839">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs837" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1001"
|
||||
id="namedview835"
|
||||
showgrid="false"
|
||||
inkscape:pagecheckerboard="false"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="19.245844"
|
||||
inkscape:cy="14.4084"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g841"
|
||||
inkscape:lockguides="false"
|
||||
inkscape:document-rotation="0" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Image"
|
||||
id="g841">
|
||||
<g
|
||||
id="g1189"
|
||||
transform="translate(-5e-7,-0.1334595)">
|
||||
<g
|
||||
id="g921"
|
||||
transform="matrix(0.73266354,0.68059102,-0.71588328,0.69821997,-0.05840962,-0.42219604)">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.50332;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
|
||||
d="M 5.6496339,3.1617897 H 25.056799 v 0.03224 H 5.6496339 Z"
|
||||
id="path923" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.50332;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
|
||||
d="M 5.6503906,2.4101562 C 5.2350485,2.4100358 4.898317,2.7467673 4.8984375,3.1621094 v 0.03125 c -1.204e-4,0.4153421 0.336611,0.7520735 0.7519531,0.7519531 H 25.056641 c 0.415342,1.204e-4 0.752073,-0.336611 0.751953,-0.7519531 L 24.737581,-0.12374013 C 24.493696,2.1372587 24.241088,2.426127 22.836001,2.4101563 h -0.981297 -1.962593 -4.538595 z"
|
||||
id="path925"
|
||||
sodipodi:nodetypes="cccccccccccc" />
|
||||
</g>
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.33469;stroke-opacity:1"
|
||||
id="rect994-7"
|
||||
width="15.036267"
|
||||
height="0.032800458"
|
||||
x="4.2540865"
|
||||
y="-19.78083"
|
||||
transform="matrix(-0.69218043,0.7217245,-0.73411036,-0.67903018,0,0)" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.31971;stroke-opacity:1"
|
||||
id="rect994-7-4"
|
||||
width="14.866495"
|
||||
height="0.032434449"
|
||||
x="26.006418"
|
||||
y="3.4238737"
|
||||
transform="matrix(0.69298606,0.72095099,0.73486654,-0.67821175,0,0)" />
|
||||
<g
|
||||
id="g921-4"
|
||||
transform="matrix(-0.73266354,0.68059102,0.71588328,0.69821997,32.107971,-0.42219604)">
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.50332;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
|
||||
d="M 5.6496339,3.1617897 H 25.056799 v 0.03224 H 5.6496339 Z"
|
||||
id="path923-2" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.50332;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
|
||||
d="M 5.6503906,2.4101562 C 5.2350485,2.4100358 4.898317,2.7467673 4.8984375,3.1621094 v 0.03125 c -1.204e-4,0.4153421 0.336611,0.7520735 0.7519531,0.7519531 H 25.056641 c 0.415342,1.204e-4 0.752073,-0.336611 0.751953,-0.7519531 L 24.737581,-0.12374013 C 24.493696,2.1372587 24.241088,2.426127 22.836001,2.4101563 h -0.981297 -1.962593 -4.538595 z"
|
||||
id="path925-2"
|
||||
sodipodi:nodetypes="cccccccccccc" />
|
||||
</g>
|
||||
<g
|
||||
id="g1055"
|
||||
transform="translate(-0.07570186)">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.0908;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="rect1343-5-0"
|
||||
width="0.70920312"
|
||||
height="0.0092054419"
|
||||
x="-1.4234889"
|
||||
y="4.4235983"
|
||||
transform="scale(-1,1)" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.75566;stroke-opacity:1"
|
||||
id="rect845-4-2-1"
|
||||
width="1.9386948"
|
||||
height="0.027632279"
|
||||
x="5.3451033"
|
||||
y="5.7705297"
|
||||
transform="matrix(0.99999998,-2.0192883e-4,-0.60923877,0.79298683,0,0)" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.75566;stroke-opacity:1"
|
||||
id="rect845-4-2-1-1"
|
||||
width="1.9386948"
|
||||
height="0.027632279"
|
||||
x="-7.0470266"
|
||||
y="1.0897269"
|
||||
transform="matrix(-2.0192883e-4,-0.99999998,0.79298683,0.60923877,0,0)" />
|
||||
</g>
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.75566;stroke-opacity:1"
|
||||
id="rect845-4-2-1-8"
|
||||
width="1.9386948"
|
||||
height="0.027632279"
|
||||
x="14.047385"
|
||||
y="5.7727451"
|
||||
transform="matrix(0.99999998,-2.0192883e-4,-0.60923877,0.79298683,0,0)" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.75566;stroke-opacity:1"
|
||||
id="rect845-4-2-1-88"
|
||||
width="1.9386948"
|
||||
height="0.027632279"
|
||||
x="22.940956"
|
||||
y="5.7750101"
|
||||
transform="matrix(0.99999998,-2.0192883e-4,-0.60923877,0.79298683,0,0)" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.75566;stroke-opacity:1"
|
||||
id="rect845-4-2-1-8-6"
|
||||
width="1.9386948"
|
||||
height="0.027632279"
|
||||
x="14.613998"
|
||||
y="-1.0194745"
|
||||
transform="matrix(2.0192883e-4,0.99999998,-0.79298683,-0.60923877,0,0)" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.75566;stroke-opacity:1"
|
||||
id="rect845-4-2-1-8-8"
|
||||
width="1.9386948"
|
||||
height="0.027632279"
|
||||
x="-8.9796991"
|
||||
y="-39.359989"
|
||||
transform="matrix(2.0192883e-4,0.99999998,-0.79298683,-0.60923877,0,0)" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.75566;stroke-opacity:1"
|
||||
id="rect845-4-2-1-8-3"
|
||||
width="1.9386948"
|
||||
height="0.027632279"
|
||||
x="31.91931"
|
||||
y="34.90218"
|
||||
transform="matrix(0.99999998,-2.0192883e-4,-0.60923877,0.79298683,0,0)" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.75566;stroke-opacity:1"
|
||||
id="rect845-4-2-1-8-64"
|
||||
width="1.9386948"
|
||||
height="0.027632279"
|
||||
x="40.643787"
|
||||
y="34.626904"
|
||||
transform="matrix(0.99999998,-2.0192883e-4,-0.60923877,0.79298683,0,0)" />
|
||||
<g
|
||||
id="g1055-7"
|
||||
transform="rotate(180,16.037851,16.023434)">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.0908;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="rect1343-5-0-1"
|
||||
width="0.70920312"
|
||||
height="0.0092054419"
|
||||
x="-1.4234889"
|
||||
y="4.4235983"
|
||||
transform="scale(-1,1)" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.75566;stroke-opacity:1"
|
||||
id="rect845-4-2-1-5"
|
||||
width="1.9386948"
|
||||
height="0.027632279"
|
||||
x="5.3451033"
|
||||
y="5.7705297"
|
||||
transform="matrix(0.99999998,-2.0192883e-4,-0.60923877,0.79298683,0,0)" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.75566;stroke-opacity:1"
|
||||
id="rect845-4-2-1-1-0"
|
||||
width="1.9386948"
|
||||
height="0.027632279"
|
||||
x="-7.0470266"
|
||||
y="1.0897269"
|
||||
transform="matrix(-2.0192883e-4,-0.99999998,0.79298683,0.60923877,0,0)" />
|
||||
</g>
|
||||
<g
|
||||
id="g1055-0"
|
||||
transform="rotate(90,16.037852,19.747164)">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.0908;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="rect1343-5-0-4"
|
||||
width="0.70920312"
|
||||
height="0.0092054419"
|
||||
x="-1.4234889"
|
||||
y="4.4235983"
|
||||
transform="scale(-1,1)" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.75566;stroke-opacity:1"
|
||||
id="rect845-4-2-1-80"
|
||||
width="1.9386948"
|
||||
height="0.027632279"
|
||||
x="5.3451033"
|
||||
y="5.7705297"
|
||||
transform="matrix(0.99999998,-2.0192883e-4,-0.60923877,0.79298683,0,0)" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.75566;stroke-opacity:1"
|
||||
id="rect845-4-2-1-1-5"
|
||||
width="1.9386948"
|
||||
height="0.027632279"
|
||||
x="-7.0470266"
|
||||
y="1.0897269"
|
||||
transform="matrix(-2.0192883e-4,-0.99999998,0.79298683,0.60923877,0,0)" />
|
||||
</g>
|
||||
<g
|
||||
id="g1055-5"
|
||||
transform="rotate(-90,12.386296,16.171311)">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.0908;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="rect1343-5-0-0"
|
||||
width="0.70920312"
|
||||
height="0.0092054419"
|
||||
x="-1.4234889"
|
||||
y="4.4235983"
|
||||
transform="scale(-1,1)" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.75566;stroke-opacity:1"
|
||||
id="rect845-4-2-1-0"
|
||||
width="1.9386948"
|
||||
height="0.027632279"
|
||||
x="5.3451033"
|
||||
y="5.7705297"
|
||||
transform="matrix(0.99999998,-2.0192883e-4,-0.60923877,0.79298683,0,0)" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.75566;stroke-opacity:1"
|
||||
id="rect845-4-2-1-1-1"
|
||||
width="1.9386948"
|
||||
height="0.027632279"
|
||||
x="-7.0470266"
|
||||
y="1.0897269"
|
||||
transform="matrix(-2.0192883e-4,-0.99999998,0.79298683,0.60923877,0,0)" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 15 KiB |
12
integrations/nextcloud/snappymail/js/admin.js
Executable file
12
integrations/nextcloud/snappymail/js/admin.js
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
/**
|
||||
* Nextcloud - SnappyMail mail plugin
|
||||
*
|
||||
* @author SnappyMail Team, Nextgen-Networks (@nextgen-networks), Tab Fitts (@tabp0le), Pierre-Alain Bandinelli (@pierre-alain-b)
|
||||
*
|
||||
* Based initially on https://github.com/SnappyMail/snappymail-webmail/tree/master/build/owncloud
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
SnappyMailFormHelper('#mail-snappymail-admin-form', 'admin.php');
|
||||
});
|
||||
12
integrations/nextcloud/snappymail/js/personal.js
Executable file
12
integrations/nextcloud/snappymail/js/personal.js
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
/**
|
||||
* Nextcloud - SnappyMail mail plugin
|
||||
*
|
||||
* @author SnappyMail Team, Nextgen-Networks (@nextgen-networks), Tab Fitts (@tabp0le), Pierre-Alain Bandinelli (@pierre-alain-b)
|
||||
*
|
||||
* Based initially on https://github.com/SnappyMail/snappymail-webmail/tree/master/build/owncloud
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
SnappyMailFormHelper('#mail-snappymail-personal-form', 'personal.php');
|
||||
});
|
||||
114
integrations/nextcloud/snappymail/js/rainloop.js
Executable file
114
integrations/nextcloud/snappymail/js/rainloop.js
Executable file
|
|
@ -0,0 +1,114 @@
|
|||
// Do the following things once the document is fully loaded.
|
||||
document.onreadystatechange = function () {
|
||||
if (document.readyState === 'complete') {
|
||||
watchIFrameTitle();
|
||||
}
|
||||
}
|
||||
|
||||
// The SnappyMail application is already configured to modify the <title> element
|
||||
// of its root document with the number of unread messages in the inbox.
|
||||
// However, its document is the SnappyMail iframe. This function sets up a
|
||||
// Mutation Observer to watch the <title> element of the iframe for changes in
|
||||
// the unread message count and propagates that to the parent <title> element,
|
||||
// allowing the unread message count to be displayed in the NC tab's text when
|
||||
// the SnappyMail app is selected.
|
||||
function watchIFrameTitle() {
|
||||
iframe = document.getElementById('rliframe');
|
||||
if (!iframe) {
|
||||
return;
|
||||
}
|
||||
target = iframe.contentDocument.getElementsByTagName('title')[0];
|
||||
config = {
|
||||
characterData: true,
|
||||
childList: true,
|
||||
subtree: true
|
||||
}
|
||||
observer = new MutationObserver(function(mutations) {
|
||||
title = mutations[0].target.innerText;
|
||||
if (title) {
|
||||
matches = title.match(/\(([0-9]+)\)/);
|
||||
if (matches) {
|
||||
document.title = '('+ matches[1] + ') ' + t('snappymail', 'Email') + ' - Nextcloud';
|
||||
} else {
|
||||
document.title = t('snappymail', 'Email') + ' - Nextcloud';
|
||||
}
|
||||
}
|
||||
});
|
||||
observer.observe(target, config);
|
||||
}
|
||||
|
||||
function SnappyMailFormHelper(sID, sAjaxFile, fCallback)
|
||||
{
|
||||
try
|
||||
{
|
||||
var
|
||||
oForm = $(sID),
|
||||
oSubmit = $('#snappymail-save-button', oForm),
|
||||
sSubmitValue = oSubmit.val(),
|
||||
oDesc = oForm.find('.snappymail-result-desc')
|
||||
;
|
||||
|
||||
oSubmit.click(function (oEvent) {
|
||||
|
||||
var oDefAjax = null;
|
||||
|
||||
oEvent.preventDefault();
|
||||
|
||||
oForm
|
||||
.addClass('snappymail-ajax')
|
||||
.removeClass('snappymail-error')
|
||||
.removeClass('snappymail-success')
|
||||
;
|
||||
|
||||
oDesc.text('');
|
||||
oSubmit.val('...');
|
||||
|
||||
oDefAjax = $.ajax({
|
||||
'type': 'POST',
|
||||
'async': true,
|
||||
'url': OC.filePath('snappymail', 'ajax', sAjaxFile),
|
||||
'data': oForm.serialize(),
|
||||
'dataType': 'json',
|
||||
'global': true
|
||||
});
|
||||
|
||||
oDefAjax.always(function (oData) {
|
||||
|
||||
var bResult = false;
|
||||
|
||||
oForm.removeClass('snappymail-ajax');
|
||||
oSubmit.val(sSubmitValue);
|
||||
|
||||
if (oData)
|
||||
{
|
||||
bResult = 'success' === oData['status'];
|
||||
if (oData['Message'])
|
||||
{
|
||||
oDesc.text(t('snappymail', oData['Message']));
|
||||
}
|
||||
}
|
||||
|
||||
if (bResult)
|
||||
{
|
||||
oForm.addClass('snappymail-success');
|
||||
}
|
||||
else
|
||||
{
|
||||
oForm.addClass('snappymail-error');
|
||||
if ('' === oDesc.text())
|
||||
{
|
||||
oDesc.text(t('snappymail', 'Error'));
|
||||
}
|
||||
}
|
||||
|
||||
if (fCallback)
|
||||
{
|
||||
fCallback(bResult, oData);
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
catch(e) {}
|
||||
}
|
||||
26
integrations/nextcloud/snappymail/js/resize.js
Executable file
26
integrations/nextcloud/snappymail/js/resize.js
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
$(function (window, document) {
|
||||
|
||||
var
|
||||
buffer = 0, //was 5 but this was creating a white space of 5px at the bottom of the page
|
||||
ifr = document.getElementById('rliframe')
|
||||
;
|
||||
|
||||
|
||||
function pageY(elem) {
|
||||
return elem.offsetParent ? (elem.offsetTop + pageY(elem.offsetParent)) : elem.offsetTop;
|
||||
}
|
||||
|
||||
function resizeIframe() {
|
||||
var height = document.documentElement.clientHeight;
|
||||
height -= pageY(ifr) + buffer;
|
||||
height = (height < 0) ? 0 : height;
|
||||
ifr.style.height = height + 'px';
|
||||
}
|
||||
|
||||
if (ifr)
|
||||
{
|
||||
ifr.onload = resizeIframe;
|
||||
window.onresize = resizeIframe;
|
||||
}
|
||||
|
||||
}(window, document));
|
||||
9
integrations/nextcloud/snappymail/l10n/en_GB.js
Normal file
9
integrations/nextcloud/snappymail/l10n/en_GB.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
OC.L10N.register(
|
||||
"snappymail",
|
||||
{
|
||||
"Email" : "Email",
|
||||
"Error" : "Error",
|
||||
"Save" : "Save",
|
||||
"Password" : "Password"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
7
integrations/nextcloud/snappymail/l10n/en_GB.json
Normal file
7
integrations/nextcloud/snappymail/l10n/en_GB.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{ "translations": {
|
||||
"Email" : "Email",
|
||||
"Error" : "Error",
|
||||
"Save" : "Save",
|
||||
"Password" : "Password"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\SnappyMail\AppInfo;
|
||||
|
||||
use OCA\SnappyMail\Util\SnappyMailHelper;
|
||||
use OCA\SnappyMail\Controller\AjaxController;
|
||||
use OCA\SnappyMail\Controller\PageController;
|
||||
|
||||
use OCP\AppFramework\App;
|
||||
use OCP\IL10N;
|
||||
use OCP\IUser;
|
||||
|
||||
class Application extends App {
|
||||
|
||||
public function __construct(array $urlParams = []) {
|
||||
parent::__construct('snappymail', $urlParams);
|
||||
|
||||
$container = $this->getContainer();
|
||||
$server = $container->getServer();
|
||||
$config = $server->getConfig();
|
||||
|
||||
/**
|
||||
* Controllers
|
||||
*/
|
||||
$container->registerService(
|
||||
'PageController', function($c) {
|
||||
return new PageController(
|
||||
$c->query('AppName'),
|
||||
$c->query('Request'),
|
||||
$c->getServer()->getAppManager(),
|
||||
$c->query('ServerContainer')->getConfig(),
|
||||
$c->getServer()->getSession()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$container->registerService(
|
||||
'AjaxController', function($c) {
|
||||
return new AjaxController(
|
||||
$c->query('AppName'),
|
||||
$c->query('Request'),
|
||||
$c->getServer()->getAppManager(),
|
||||
$c->query('ServerContainer')->getConfig(),
|
||||
$c->query(IL10N::class)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Utils
|
||||
*/
|
||||
$container->registerService(
|
||||
'SnappyMailHelper', function($c) {
|
||||
return new SnappyMailHelper(
|
||||
$c->getServer()->getConfig(),
|
||||
$c->getServer()->getUserSession(),
|
||||
$c->getServer()->getAppManager(),
|
||||
$c->getServer()->getSession()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Add script js/snappymail.js
|
||||
\OCP\Util::addScript('snappymail', 'snappymail');
|
||||
}
|
||||
|
||||
public function registerNavigation() {
|
||||
$container = $this->getContainer();
|
||||
|
||||
$container->query('OCP\INavigationManager')->add(function () use ($container) {
|
||||
$urlGenerator = $container->query('OCP\IURLGenerator');
|
||||
return [
|
||||
'id' => 'snappymail',
|
||||
'order' => 10,
|
||||
'href' => $urlGenerator->linkToRoute('snappymail.page.index'),
|
||||
'icon' => $urlGenerator->imagePath('snappymail', 'snappymail.svg'),
|
||||
'name' => \OCP\Util::getL10N('snappymail')->t('Email')
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
public function registerPersonalSettings() {
|
||||
\OCP\App::registerPersonal('snappymail', 'templates/personal');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\SnappyMail\Controller;
|
||||
|
||||
use OCA\SnappyMail\Util\SnappyMailHelper;
|
||||
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\IConfig;
|
||||
use OCP\IL10N;
|
||||
use OCP\IRequest;
|
||||
|
||||
class AjaxController extends Controller {
|
||||
private $config;
|
||||
private $appManager;
|
||||
|
||||
public function __construct(string $appName, IRequest $request, IAppManager $appManager, IConfig $config, IL10N $l) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->config = $config;
|
||||
$this->appManager = $appManager;
|
||||
$this->l = $l;
|
||||
}
|
||||
|
||||
public function setAdmin(): JSONResponse {
|
||||
try {
|
||||
$sUrl = '';
|
||||
$sPath = '';
|
||||
$bAutologin = false;
|
||||
|
||||
if (isset($_POST['appname']) && 'snappymail' === $_POST['appname']) {
|
||||
$this->config->setAppValue('snappymail', 'snappymail-autologin',
|
||||
isset($_POST['snappymail-autologin']) ? '1' === $_POST['snappymail-autologin'] : false);
|
||||
$this->config->setAppValue('snappymail', 'snappymail-autologin-with-email',
|
||||
isset($_POST['snappymail-autologin']) ? '2' === $_POST['snappymail-autologin'] : false);
|
||||
$bAutologin = $this->config->getAppValue('snappymail', 'snappymail-autologin', false);
|
||||
} else {
|
||||
return new JSONResponse([
|
||||
'status' => 'error',
|
||||
'Message' => $this->l->t('Invalid argument(s)')
|
||||
]);
|
||||
}
|
||||
|
||||
return new JSONResponse([
|
||||
'status' => 'success',
|
||||
'Message' => $this->l->t('Saved successfully')
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
return new JSONResponse([
|
||||
'status' => 'error',
|
||||
'Message' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
public function setPersonal(): JSONResponse {
|
||||
try {
|
||||
|
||||
if (isset($_POST['appname'], $_POST['snappymail-password'], $_POST['snappymail-email']) && 'snappymail' === $_POST['appname']) {
|
||||
$sUser = \OC::$server->getUserSession()->getUser()->getUID();
|
||||
|
||||
$sPostEmail = $_POST['snappymail-email'];
|
||||
$this->config->setUserValue($sUser, 'snappymail', 'snappymail-email', $sPostEmail);
|
||||
|
||||
$sPass = $_POST['snappymail-password'];
|
||||
if ('******' !== $sPass && '' !== $sPass) {
|
||||
include_once $this->appManager->getAppPath('snappymail').'/lib/Util/SnappyMailHelper.php';
|
||||
|
||||
$this->config->setUserValue($sUser, 'snappymail', 'snappymail-password',
|
||||
SnappyMailHelper::encodePassword($sPass, md5($sPostEmail)));
|
||||
}
|
||||
|
||||
$sEmail = $this->config->getUserValue($sUser, 'snappymail', 'snappymail-email', '');
|
||||
} else {
|
||||
return new JSONResponse([
|
||||
'status' => 'error',
|
||||
'Message' => $this->l->t('Invalid argument(s)'),
|
||||
'Email' => $sEmail
|
||||
]);
|
||||
}
|
||||
|
||||
return new JSONResponse([
|
||||
'status' => 'success',
|
||||
'Message' => $this->l->t('Saved successfully'),
|
||||
'Email' => $sEmail
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
return new JSONResponse([
|
||||
'status' => 'error',
|
||||
'Message' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\SnappyMail\Controller;
|
||||
|
||||
use OCA\SnappyMail\Util\SnappyMailHelper;
|
||||
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\ContentSecurityPolicy;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\IConfig;
|
||||
use OCP\IRequest;
|
||||
use OCP\ISession;
|
||||
|
||||
class PageController extends Controller {
|
||||
private $userId;
|
||||
private $config;
|
||||
private $appManager;
|
||||
private $appPath;
|
||||
private $session;
|
||||
|
||||
public function __construct($AppName, IRequest $request, IAppManager $appManager, IConfig $config, ISession $session) {
|
||||
parent::__construct($AppName, $request);
|
||||
$this->appPath = $appManager->getAppPath('snappymail');
|
||||
$this->config = $config;
|
||||
$this->appManager = $appManager;
|
||||
$this->session = $session;
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function index() {
|
||||
\OC::$server->getNavigationManager()->setActiveEntry('snappymail');
|
||||
|
||||
\OCP\Util::addStyle('snappymail', 'style');
|
||||
|
||||
$sUrl = SnappyMailHelper::normalizeUrl(SnappyMailHelper::getAppUrl());
|
||||
|
||||
$params = [
|
||||
'snappymail-iframe-url' => SnappyMailHelper::normalizeUrl($sUrl).'?OwnCloudAuth'
|
||||
];
|
||||
|
||||
$response = new TemplateResponse('snappymail', 'index', $params);
|
||||
|
||||
$csp = new ContentSecurityPolicy();
|
||||
$csp->addAllowedFrameDomain("'self'");
|
||||
$response->setContentSecurityPolicy($csp);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function appGet() {
|
||||
$this->app();
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function appPost() {
|
||||
$this->app();
|
||||
}
|
||||
|
||||
public function app() {
|
||||
|
||||
SnappyMailHelper::regSnappyMailDataFunction();
|
||||
|
||||
if (isset($_GET['OwnCloudAuth'])) {
|
||||
$sEmail = '';
|
||||
$sEncodedPassword = '';
|
||||
|
||||
$sUser = \OC::$server->getUserSession()->getUser()->getUID();
|
||||
|
||||
if ($this->config->getAppValue('snappymail', 'snappymail-autologin', false)) {
|
||||
$sEmail = $sUser;
|
||||
$sPasswordSalt = $sUser;
|
||||
$sEncodedPassword = $this->session['snappymail-autologin-password'];
|
||||
} else if ($this->config->getAppValue('snappymail', 'snappymail-autologin-with-email', false)) {
|
||||
$sEmail = $this->config->getUserValue($sUser, 'settings', 'email', '');
|
||||
$sPasswordSalt = $sUser;
|
||||
$sEncodedPassword = $this->session['snappymail-autologin-password'];
|
||||
}
|
||||
|
||||
// If the user has set credentials for SnappyMail in their personal
|
||||
// settings, override everything before and use those instead.
|
||||
$sIndividualEmail = $this->config->getUserValue($sUser, 'snappymail', 'snappymail-email', '');
|
||||
if ($sIndividualEmail) {
|
||||
$sEmail = $sIndividualEmail;
|
||||
$sPasswordSalt = $sEmail;
|
||||
$sEncodedPassword = $this->config->getUserValue($sUser, 'snappymail', 'snappymail-password', '');
|
||||
}
|
||||
|
||||
$sDecodedPassword = SnappyMailHelper::decodePassword($sEncodedPassword, md5($sPasswordSalt));
|
||||
|
||||
$_ENV['___snappymail_owncloud_email'] = $sEmail;
|
||||
$_ENV['___snappymail_owncloud_password'] = $sDecodedPassword;
|
||||
}
|
||||
|
||||
include $this->appPath . '/app/index.php';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
namespace OCA\SnappyMail\Settings;
|
||||
|
||||
use OCA\SnappyMail\Util\SnappyMailHelper;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\IConfig;
|
||||
use OCP\Settings\ISettings;
|
||||
|
||||
class AdminSettings implements ISettings {
|
||||
|
||||
private $config;
|
||||
|
||||
public function __construct(IConfig $config) {
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function getForm() {
|
||||
$keys = [
|
||||
'snappymail-autologin',
|
||||
'snappymail-autologin-with-email'
|
||||
];
|
||||
|
||||
$parameters = [];
|
||||
foreach ($keys as $k) {
|
||||
$v = $this->config->getAppValue('snappymail', $k);
|
||||
$parameters[$k] = $v;
|
||||
}
|
||||
|
||||
$uid = \OC::$server->getUserSession()->getUser()->getUID();
|
||||
if (\OC_User::isAdminUser($uid)) {
|
||||
$parameters['snappymail-admin-panel-link'] = SnappyMailHelper::getAppUrl().'?admin';
|
||||
}
|
||||
|
||||
return new TemplateResponse('snappymail', 'admin-local', $parameters);
|
||||
}
|
||||
|
||||
public function getSection() {
|
||||
return 'additional';
|
||||
}
|
||||
|
||||
public function getPriority() {
|
||||
return 50;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
namespace OCA\SnappyMail\Settings;
|
||||
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\IConfig;
|
||||
|
||||
class PersonalSettings {
|
||||
private $config;
|
||||
|
||||
public function __construct(IConfig $config) {
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function getForm() {
|
||||
$uid = \OC::$server->getUserSession()->getUser()->getUID();
|
||||
|
||||
$keys = [
|
||||
'snappymail-email',
|
||||
'snappymail-password'
|
||||
];
|
||||
|
||||
$parameters = [];
|
||||
foreach ($keys as $k) {
|
||||
$v = $this->config->getUserValue($uid, 'snappymail', $k);
|
||||
$parameters[$k] = $v;
|
||||
}
|
||||
|
||||
return new TemplateResponse('snappymail', 'personal_settings', $parameters, '');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
341
integrations/nextcloud/snappymail/lib/Util/SnappyMailHelper.php
Normal file
341
integrations/nextcloud/snappymail/lib/Util/SnappyMailHelper.php
Normal file
|
|
@ -0,0 +1,341 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\SnappyMail\Util;
|
||||
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\IConfig;
|
||||
use OCP\ISession;
|
||||
use OCP\IUserSession;
|
||||
|
||||
class SnappyMailHelper {
|
||||
|
||||
private $appManager;
|
||||
private $config;
|
||||
private $session;
|
||||
private $userSession;
|
||||
|
||||
public function __construct(IConfig $config, IUserSession $userSession, IAppManager $appManager, ISession $session) {
|
||||
$this->appManager = $appManager;
|
||||
$this->config = $config;
|
||||
$this->userSession = $userSession;
|
||||
$this->session = $session;
|
||||
}
|
||||
|
||||
public function registerHooks() {
|
||||
$this->userSession->listen('\OC\User', 'postLogin', function($user, $loginName, $password, $isTokenLogin) {
|
||||
$this->login($user, $loginName, $password, $isTokenLogin, $this->config, $this->session);
|
||||
});
|
||||
|
||||
$this->userSession->listen('\OC\User', 'logout', function() {
|
||||
$this->logout($this->appManager, $this->config, $this->session);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getAppUrl()
|
||||
{
|
||||
$sRequestUri = \OC::$server->getURLGenerator()->linkToRoute('snappymail.page.appGet');
|
||||
if ($sRequestUri)
|
||||
{
|
||||
return $sRequestUri;
|
||||
}
|
||||
|
||||
$sRequestUri = empty($_SERVER['REQUEST_URI']) ? '': trim($_SERVER['REQUEST_URI']);
|
||||
$sRequestUri = preg_replace('/index.php\/.+$/', 'index.php/', $sRequestUri);
|
||||
$sRequestUri = $sRequestUri.'apps/snappymail/app/';
|
||||
|
||||
return '/'.ltrim($sRequestUri, '/\\');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPath
|
||||
* @param string $sEmail
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getSsoHash($sPath, $sEmail, $sPassword)
|
||||
{
|
||||
$SsoHash = '';
|
||||
|
||||
$sPath = rtrim(trim($sPath), '\\/').'/index.php';
|
||||
if (file_exists($sPath))
|
||||
{
|
||||
self::regSnappyMailDataFunction();
|
||||
|
||||
$_ENV['RAINLOOP_INCLUDE_AS_API'] = true;
|
||||
include $sPath;
|
||||
|
||||
if (class_exists('\\SnappyMail\\Api'))
|
||||
{
|
||||
$SsoHash = \SnappyMail\Api::GetUserSsoHash($sEmail, $sPassword);
|
||||
}
|
||||
}
|
||||
|
||||
return $SsoHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sUrl
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function normalizeUrl($sUrl)
|
||||
{
|
||||
$sUrl = rtrim(trim($sUrl), '/\\');
|
||||
if ('.php' !== strtolower(substr($sUrl, -4)))
|
||||
{
|
||||
$sUrl .= '/';
|
||||
}
|
||||
|
||||
return $sUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public static function mcryptSupported()
|
||||
{
|
||||
return function_exists('mcrypt_encrypt') &&
|
||||
function_exists('mcrypt_decrypt') &&
|
||||
defined('MCRYPT_RIJNDAEL_256') &&
|
||||
defined('MCRYPT_MODE_ECB');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function openSslSupportedMethod()
|
||||
{
|
||||
$method = 'AES-256-CBC';
|
||||
return function_exists('openssl_encrypt') &&
|
||||
function_exists('openssl_decrypt') &&
|
||||
function_exists('openssl_random_pseudo_bytes') &&
|
||||
function_exists('openssl_cipher_iv_length') &&
|
||||
function_exists('openssl_get_cipher_methods') &&
|
||||
defined('OPENSSL_RAW_DATA') && defined('OPENSSL_ZERO_PADDING') &&
|
||||
in_array($method, openssl_get_cipher_methods()) ? $method : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sMethod
|
||||
* @param string $sPassword
|
||||
* @param string $sSalt
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function encodePasswordSsl($sMethod, $sPassword, $sSalt)
|
||||
{
|
||||
$sData = base64_encode($sPassword);
|
||||
|
||||
$iv = @openssl_random_pseudo_bytes(openssl_cipher_iv_length($sMethod));
|
||||
$r = @openssl_encrypt($sData, $sMethod, md5($sSalt), OPENSSL_RAW_DATA, $iv);
|
||||
|
||||
return @base64_encode(base64_encode($r).'|'.base64_encode($iv));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sMethod
|
||||
* @param string $sPassword
|
||||
* @param string $sSalt
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function decodePasswordSsl($sMethod, $sPassword, $sSalt)
|
||||
{
|
||||
$sLine = base64_decode(trim($sPassword));
|
||||
$aParts = explode('|', $sLine, 2);
|
||||
|
||||
if (is_array($aParts) && !empty($aParts[0]) && !empty($aParts[1])) {
|
||||
|
||||
$sData = @base64_decode($aParts[0]);
|
||||
$iv = @base64_decode($aParts[1]);
|
||||
|
||||
return @base64_decode(trim(
|
||||
@openssl_decrypt($sData, $sMethod, md5($sSalt), OPENSSL_RAW_DATA, $iv)
|
||||
));
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
* @param string $sSalt
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function encodePassword($sPassword, $sSalt)
|
||||
{
|
||||
$method = self::openSslSupportedMethod();
|
||||
if ($method)
|
||||
{
|
||||
return self::encodePasswordSsl($method, $sPassword, $sSalt);
|
||||
}
|
||||
else if (self::mcryptSupported())
|
||||
{
|
||||
return @trim(base64_encode(
|
||||
@mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($sSalt), base64_encode($sPassword), MCRYPT_MODE_ECB)
|
||||
));
|
||||
}
|
||||
|
||||
return @trim(base64_encode($sPassword));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
* @param string $sSalt
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function decodePassword($sPassword, $sSalt)
|
||||
{
|
||||
$method = self::openSslSupportedMethod();
|
||||
if ($method)
|
||||
{
|
||||
return self::decodePasswordSsl($method, $sPassword, $sSalt);
|
||||
}
|
||||
else if (self::mcryptSupported())
|
||||
{
|
||||
return @base64_decode(trim(
|
||||
@mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($sSalt), base64_decode(trim($sPassword)), MCRYPT_MODE_ECB)
|
||||
));
|
||||
}
|
||||
|
||||
return @base64_decode(trim($sPassword));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aParams
|
||||
* @return boolean
|
||||
* @UseSession
|
||||
*/
|
||||
public static function login($user, $loginName, $password, $isTokenLogin, $config, &$session)
|
||||
{
|
||||
$sUser = $user->getUID();
|
||||
|
||||
$sEmail = $sUser;
|
||||
$sPassword = $password;
|
||||
$sEncodedPassword = self::encodePassword($sPassword, md5($sEmail));
|
||||
|
||||
// Only store the user's password in the current session if they have
|
||||
// enabled auto-login using Nextcloud username or email address.
|
||||
if ($config->getAppValue('snappymail', 'snappymail-autologin') || $config->getAppValue('snappymail', 'snappymail-autologin-with-email')) {
|
||||
$session['snappymail-autologin-password'] = $sEncodedPassword;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @UseSession
|
||||
*/
|
||||
public static function logout($appManager, $config, &$session)
|
||||
{
|
||||
$session['snappymail-autologin-password'] = '';
|
||||
|
||||
$sApiPath = $appManager->getAppPath('snappymail') . '/app/index.php';
|
||||
|
||||
self::regSnappyMailDataFunction();
|
||||
|
||||
$_ENV['RAINLOOP_INCLUDE_AS_API'] = true;
|
||||
include $sApiPath;
|
||||
|
||||
\SnappyMail\Api::LogoutCurrentLogginedUser();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function regSnappyMailDataFunction()
|
||||
{
|
||||
if (!@function_exists('__get_custom_data_full_path'))
|
||||
{
|
||||
$_ENV['SNAPPYMAIL_NEXTCLOUD'] = true;
|
||||
|
||||
function __get_custom_data_full_path()
|
||||
{
|
||||
$sData = rtrim(trim(OC::$server->getSystemConfig()->getValue('datadirectory', '')), '\\/').'/';
|
||||
return @is_dir($sData) ? $sData.'snappymail-storage' : '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function mimeContentType($filename) {
|
||||
|
||||
$mime_types = array(
|
||||
|
||||
'woff' => 'application/font-woff',
|
||||
|
||||
'txt' => 'text/plain',
|
||||
'htm' => 'text/html',
|
||||
'html' => 'text/html',
|
||||
'php' => 'text/html',
|
||||
'css' => 'text/css',
|
||||
'js' => 'application/javascript',
|
||||
'json' => 'application/json',
|
||||
'xml' => 'application/xml',
|
||||
'swf' => 'application/x-shockwave-flash',
|
||||
'flv' => 'video/x-flv',
|
||||
|
||||
// images
|
||||
'png' => 'image/png',
|
||||
'jpe' => 'image/jpeg',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'jpg' => 'image/jpeg',
|
||||
'gif' => 'image/gif',
|
||||
'bmp' => 'image/bmp',
|
||||
'ico' => 'image/vnd.microsoft.icon',
|
||||
'tiff' => 'image/tiff',
|
||||
'tif' => 'image/tiff',
|
||||
'svg' => 'image/svg+xml',
|
||||
'svgz' => 'image/svg+xml',
|
||||
|
||||
// archives
|
||||
'zip' => 'application/zip',
|
||||
'rar' => 'application/x-rar-compressed',
|
||||
'exe' => 'application/x-msdownload',
|
||||
'msi' => 'application/x-msdownload',
|
||||
'cab' => 'application/vnd.ms-cab-compressed',
|
||||
|
||||
// audio/video
|
||||
'mp3' => 'audio/mpeg',
|
||||
'qt' => 'video/quicktime',
|
||||
'mov' => 'video/quicktime',
|
||||
|
||||
// adobe
|
||||
'pdf' => 'application/pdf',
|
||||
'psd' => 'image/vnd.adobe.photoshop',
|
||||
'ai' => 'application/postscript',
|
||||
'eps' => 'application/postscript',
|
||||
'ps' => 'application/postscript',
|
||||
|
||||
// ms office
|
||||
'doc' => 'application/msword',
|
||||
'rtf' => 'application/rtf',
|
||||
'xls' => 'application/vnd.ms-excel',
|
||||
'ppt' => 'application/vnd.ms-powerpoint',
|
||||
|
||||
// open office
|
||||
'odt' => 'application/vnd.oasis.opendocument.text',
|
||||
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
|
||||
);
|
||||
|
||||
if (0 < strpos($filename, '.'))
|
||||
{
|
||||
$ext = strtolower(array_pop(explode('.',$filename)));
|
||||
if (array_key_exists($ext, $mime_types))
|
||||
{
|
||||
return $mime_types[$ext];
|
||||
}
|
||||
else if (function_exists('finfo_open'))
|
||||
{
|
||||
$finfo = finfo_open(FILEINFO_MIME);
|
||||
$mimetype = finfo_file($finfo, $filename);
|
||||
finfo_close($finfo);
|
||||
return $mimetype;
|
||||
}
|
||||
}
|
||||
|
||||
return 'application/octet-stream';
|
||||
}
|
||||
}
|
||||
45
integrations/nextcloud/snappymail/templates/admin-local.php
Executable file
45
integrations/nextcloud/snappymail/templates/admin-local.php
Executable file
|
|
@ -0,0 +1,45 @@
|
|||
<?php script('snappymail', 'admin') ?>
|
||||
|
||||
<div class="section">
|
||||
<form id="mail-snappymail-admin-form" action="#" method="post">
|
||||
<input type="hidden" name="requesttoken" value="<?php echo $_['requesttoken'] ?>" id="requesttoken">
|
||||
<input type="hidden" name="appname" value="snappymail">
|
||||
|
||||
<fieldset class="personalblock">
|
||||
<h2><?php echo($l->t('SnappyMail Webmail')); ?></h2>
|
||||
<br />
|
||||
<?php if ($_['snappymail-admin-panel-link']): ?>
|
||||
<p>
|
||||
<a href="<?php echo $_['snappymail-admin-panel-link'] ?>" target="_blank" style="text-decoration: underline">
|
||||
<?php echo($l->t('Go to SnappyMail Webmail admin panel')); ?>
|
||||
</a>
|
||||
</p>
|
||||
<br />
|
||||
<?php endif; ?>
|
||||
<p>
|
||||
<div style="display: flex;">
|
||||
<input type="radio" id="snappymail-noautologin" name="snappymail-autologin" value="0" <?php if (!$_['snappymail-autologin']&&!$_['snappymail-autologin-with-email']): ?>checked="checked"<?php endif; ?> />
|
||||
<label style="margin: auto 5px;" for="snappymail-noautologin">
|
||||
<?php echo($l->t('Users will login manually, or define credentials in their personal settings for automatic logins.')); ?>
|
||||
</label>
|
||||
</div>
|
||||
<div style="display: flex;">
|
||||
<input type="radio" id="snappymail-autologin" name="snappymail-autologin" value="1" <?php if ($_['snappymail-autologin']): ?>checked="checked"<?php endif; ?> />
|
||||
<label style="margin: auto 5px;" for="snappymail-autologin">
|
||||
<?php echo($l->t('Attempt to automatically login users with their Nextcloud username and password, or user-defined credentials, if set.')); ?>
|
||||
</label>
|
||||
</div>
|
||||
<div style="display: flex;">
|
||||
<input type="radio" id="snappymail-autologin-with-email" name="snappymail-autologin" value="2" <?php if ($_['snappymail-autologin-with-email']): ?>checked="checked"<?php endif; ?> />
|
||||
<label style="margin: auto 5px;" for="snappymail-autologin-with-email">
|
||||
<?php echo($l->t('Attempt to automatically login users with their Nextcloud email and password, or user-defined credentials, if set.')); ?>
|
||||
</label>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
<input type="button" id="snappymail-save-button" name="snappymail-save-button" value="<?php echo($l->t('Save')); ?>" />
|
||||
<span class="snappymail-result-desc"></span>
|
||||
</p>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
1
integrations/nextcloud/snappymail/templates/empty.php
Executable file
1
integrations/nextcloud/snappymail/templates/empty.php
Executable file
|
|
@ -0,0 +1 @@
|
|||
<!-- empty -->
|
||||
3
integrations/nextcloud/snappymail/templates/index-empty.php
Executable file
3
integrations/nextcloud/snappymail/templates/index-empty.php
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
<div style="margin: 20px">
|
||||
<?php p($l->t('SnappyMail Webmail is not configured yet.')); ?>
|
||||
</div>
|
||||
1
integrations/nextcloud/snappymail/templates/index.php
Executable file
1
integrations/nextcloud/snappymail/templates/index.php
Executable file
|
|
@ -0,0 +1 @@
|
|||
<iframe id="rliframe" style="border: none; width: 100%; height: 100%; position: relative;" tabindex="-1" frameborder="0" src="<?php echo $_['snappymail-iframe-url']; ?>"></iframe><?php OCP\Util::addScript('snappymail', 'resize');
|
||||
8
integrations/nextcloud/snappymail/templates/personal.php
Executable file
8
integrations/nextcloud/snappymail/templates/personal.php
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
use OCA\SnappyMail\Settings\PersonalSettings;
|
||||
|
||||
$app = new \OCA\SnappyMail\AppInfo\Application();
|
||||
$controller = $app->getContainer()->query(PersonalSettings::class);
|
||||
return $controller->getForm()->render();
|
||||
|
||||
32
integrations/nextcloud/snappymail/templates/personal_settings.php
Executable file
32
integrations/nextcloud/snappymail/templates/personal_settings.php
Executable file
|
|
@ -0,0 +1,32 @@
|
|||
<?php script('snappymail', 'personal');
|
||||
|
||||
$textLink1 = $l->t('may have some');
|
||||
$textLink2 = $l->t('security considerations');
|
||||
$links = [
|
||||
"<a href=\"https://github.com/pierre-alain-b/rainloop-nextcloud/issues/87\" style=\"text-decoration:underline\" target=\"_blank\">{$textLink1}</a>",
|
||||
"<a href=\"https://github.com/RainLoop/rainloop-webmail/issues/1082\" style=\"text-decoration:underline\" target=\"_blank\">{$textLink2}</a>"
|
||||
]; ?>
|
||||
|
||||
<div class="section">
|
||||
<form id="mail-snappymail-personal-form" action="#" method="post">
|
||||
<input type="hidden" name="requesttoken" value="<?php echo $_['requesttoken'] ?>" id="requesttoken">
|
||||
<input type="hidden" name="appname" value="snappymail">
|
||||
|
||||
<fieldset class="personalblock">
|
||||
<h2><?php echo($l->t('SnappyMail Webmail')); ?></h2>
|
||||
<p>
|
||||
<?php echo($l->t('Enter an email and password to auto-login to SnappyMail. <b>Please note</b> that this feature %s %s.', $links)); ?>
|
||||
</p>
|
||||
<p>
|
||||
<input type="text" id="snappymail-email" name="snappymail-email"
|
||||
value="<?php echo $_['snappymail-email']; ?>" placeholder="<?php echo($l->t('Email')); ?>" />
|
||||
|
||||
<input type="password" id="snappymail-password" name="snappymail-password"
|
||||
value="<?php echo $_['snappymail-password']; ?>" placeholder="<?php echo($l->t('Password')); ?>" />
|
||||
|
||||
<input type="button" id="snappymail-save-button" name="snappymail-save-button" value="<?php echo($l->t('Save')); ?>" />
|
||||
<span class="snappymail-result-desc"></span>
|
||||
</p>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
107
plugins/nextcloud/NextCloudSuggestions.php
Normal file
107
plugins/nextcloud/NextCloudSuggestions.php
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
class OwnCloudSuggestions implements \RainLoop\Providers\Suggestions\ISuggestions
|
||||
{
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
protected $oLogger;
|
||||
|
||||
public function Process(\RainLoop\Model\Account $oAccount, string $sQuery, int $iLimit = 20): array
|
||||
{
|
||||
$iInputLimit = $iLimit;
|
||||
$aResult = array();
|
||||
$sQuery = \trim($sQuery);
|
||||
|
||||
try
|
||||
{
|
||||
if ('' === $sQuery || !$oAccount || !OwnCloudPlugin::IsOwnCloudLoggedIn())
|
||||
{
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
$aParams = array('FN', 'NICKNAME', 'TITLE', 'EMAIL');
|
||||
if (\class_exists('OC') && isset(\OC::$server) && \method_exists(\OC::$server, 'getContactsManager'))
|
||||
{
|
||||
$cm = \OC::$server->getContactsManager();
|
||||
if (!$cm && !$cm->isEnabled())
|
||||
{
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
$aSearchResult = $cm->search($sQuery, $aParams);
|
||||
}
|
||||
else if (\class_exists('OCP\Contacts') && \OCP\Contacts::isEnabled())
|
||||
{
|
||||
$aSearchResult = \OCP\Contacts::search($sQuery, $aParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
//$this->oLogger->WriteDump($aSearchResult);
|
||||
|
||||
$aHashes = array();
|
||||
if (\is_array($aSearchResult) && 0 < \count($aSearchResult))
|
||||
{
|
||||
foreach ($aSearchResult as $aContact)
|
||||
{
|
||||
if (0 >= $iLimit)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
$sUid = empty($aContact['UID']) ? '' : $aContact['UID'];
|
||||
if (!empty($sUid))
|
||||
{
|
||||
$mEmails = isset($aContact['EMAIL']) ? $aContact['EMAIL'] : '';
|
||||
|
||||
$sFullName = isset($aContact['FN']) ? \trim($aContact['FN']) : '';
|
||||
if (empty($sFullName))
|
||||
{
|
||||
$sFullName = isset($aContact['NICKNAME']) ? \trim($aContact['NICKNAME']) : '';
|
||||
}
|
||||
|
||||
if (!\is_array($mEmails))
|
||||
{
|
||||
$mEmails = array($mEmails);
|
||||
}
|
||||
|
||||
foreach ($mEmails as $sEmail)
|
||||
{
|
||||
$sHash = '"'.$sFullName.'" <'.$sEmail.'>';
|
||||
if (!isset($aHashes[$sHash]))
|
||||
{
|
||||
$aHashes[$sHash] = true;
|
||||
$aResult[] = array($sEmail, $sFullName);
|
||||
$iLimit--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$aResult = \array_slice($aResult, 0, $iInputLimit);
|
||||
}
|
||||
|
||||
unset($aSearchResult, $aHashes);
|
||||
}
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
}
|
||||
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*/
|
||||
public function SetLogger($oLogger)
|
||||
{
|
||||
$this->oLogger = $oLogger instanceof \MailSo\Log\Logger ? $oLogger : null;
|
||||
}
|
||||
}
|
||||
180
plugins/nextcloud/index.php
Normal file
180
plugins/nextcloud/index.php
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
<?php
|
||||
|
||||
class NextCloudPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
const
|
||||
NAME = 'NextCloud',
|
||||
VERSION = '2.0',
|
||||
CATEGORY = 'Integrations',
|
||||
DESCRIPTION = 'Plugin that adds functionality to integrate with NextCloud.';
|
||||
|
||||
private static function IsNextCloud() : bool
|
||||
{
|
||||
return !empty($_ENV['SNAPPYMAIL_NEXTCLOUD']) && \class_exists('OC');
|
||||
}
|
||||
|
||||
private static function IsNextCloudLoggedIn() : bool
|
||||
{
|
||||
return static::IsNextCloud() && \class_exists('OCP\User') && \OCP\User::isLoggedIn();
|
||||
}
|
||||
|
||||
public function Init() : void
|
||||
{
|
||||
if (static::IsNextCloud()) {
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
$this->addHook('filter.app-data', 'FilterAppData');
|
||||
$this->addHook('json.attachments', 'DoAttachmentsActions');
|
||||
|
||||
$sAppPath = '';
|
||||
if (\class_exists('OC_App')) {
|
||||
$sAppPath = \rtrim(\trim(\OC_App::getAppWebPath('snappymail')), '\\/').'/app/';
|
||||
}
|
||||
if (!$sAppPath) {
|
||||
$sUrl = \MailSo\Base\Http::SingletonInstance()->GetUrl();
|
||||
if ($sUrl && \preg_match('/\/index\.php\/apps\/snappymail/', $sUrl)) {
|
||||
$sAppPath = \preg_replace('/\/index\.php\/apps\/snappymail.+$/',
|
||||
'/apps/snappymail/app/', $sUrl);
|
||||
}
|
||||
}
|
||||
$_SERVER['SCRIPT_NAME'] = $sAppPath;
|
||||
}
|
||||
}
|
||||
|
||||
public function Supported() : string
|
||||
{
|
||||
if (!static::IsNextCloud()) {
|
||||
return 'NextCloud not found to use this plugin';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// DoAttachmentsActions
|
||||
public function DoAttachmentsActions(\SnappyMail\AttachmentsAction $data)
|
||||
{
|
||||
if ('nextcloud' === $data->action) {
|
||||
if (static::IsNextCloudLoggedIn() && \class_exists('OCP\Files')) {
|
||||
$oFiles = \OCP\Files::getStorage('files');
|
||||
if ($oFiles && $data->filesProvider->IsActive() && \method_exists($oFiles, 'file_put_contents')) {
|
||||
$sSaveFolder = $this->Config()->Get('plugin', 'save_folder', '') ?: 'Attachments';
|
||||
$oFiles->is_dir($sSaveFolder) || $oFiles->mkdir($sSaveFolder);
|
||||
$data->result = true;
|
||||
foreach ($data->items as $aItem) {
|
||||
$sSavedFileName = isset($aItem['FileName']) ? $aItem['FileName'] : 'file.dat';
|
||||
$sSavedFileHash = !empty($aItem['FileHash']) ? $aItem['FileHash'] : '';
|
||||
if (!empty($sSavedFileHash)) {
|
||||
$fFile = $data->filesProvider->GetFile($data->account, $sSavedFileHash, 'rb');
|
||||
if (\is_resource($fFile)) {
|
||||
$sSavedFileNameFull = \MailSo\Base\Utils::SmartFileExists($sSaveFolder.'/'.$sSavedFileName, function ($sPath) use ($oFiles) {
|
||||
return $oFiles->file_exists($sPath);
|
||||
});
|
||||
|
||||
if (!$oFiles->file_put_contents($sSavedFileNameFull, $fFile)) {
|
||||
$data->result = false;
|
||||
}
|
||||
|
||||
if (\is_resource($fFile)) {
|
||||
\fclose($fFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($data->items as $aItem) {
|
||||
$sFileHash = (string) (isset($aItem['FileHash']) ? $aItem['FileHash'] : '');
|
||||
if (!empty($sFileHash)) {
|
||||
$data->filesProvider->Clear($data->account, $sFileHash);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: create pre-login auth hook
|
||||
*/
|
||||
public function ServiceNextCloudAuth()
|
||||
{
|
||||
/*
|
||||
$this->oHttp->ServerNoCache();
|
||||
|
||||
if (!static::IsNextCloud() ||
|
||||
!isset($_ENV['___snappymail_nextcloud_email']) ||
|
||||
!isset($_ENV['___snappymail_nextcloud_password']) ||
|
||||
empty($_ENV['___snappymail_nextcloud_email'])
|
||||
)
|
||||
{
|
||||
$this->oActions->SetAuthLogoutToken();
|
||||
$this->oActions->Location('./');
|
||||
return '';
|
||||
}
|
||||
|
||||
$bLogout = true;
|
||||
|
||||
$sEmail = $_ENV['___snappymail_nextcloud_email'];
|
||||
$sPassword = $_ENV['___snappymail_nextcloud_password'];
|
||||
|
||||
try
|
||||
{
|
||||
$oAccount = $this->oActions->LoginProcess($sEmail, $sPassword);
|
||||
$this->oActions->AuthToken($oAccount);
|
||||
|
||||
$bLogout = !($oAccount instanceof \snappymail\Model\Account);
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$this->oActions->Logger()->WriteException($oException);
|
||||
}
|
||||
|
||||
if ($bLogout)
|
||||
{
|
||||
$this->oActions->SetAuthLogoutToken();
|
||||
}
|
||||
|
||||
$this->oActions->Location('./');
|
||||
return '';
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function FilterAppData($bAdmin, &$aResult)
|
||||
{
|
||||
if (!$bAdmin && \is_array($aResult) && static::IsNextCloud()) {
|
||||
$key = \array_search(\RainLoop\Enumerations\Capa::AUTOLOGOUT, $aResult['Capa']);
|
||||
if (false !== $key) {
|
||||
unset($aResult['Capa'][$key]);
|
||||
}
|
||||
if (static::IsNextCloudLoggedIn() && \class_exists('OCP\Files')) {
|
||||
$aResult['System']['attachmentsActions'][] = 'nextcloud';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $mResult
|
||||
*/
|
||||
public function MainFabrica($sName, &$mResult)
|
||||
{
|
||||
if ('suggestions' === $sName && static::IsNextCloud() && $this->Config()->Get('plugin', 'suggestions', true)) {
|
||||
include_once __DIR__.'/NextCloudSuggestions.php';
|
||||
if (!\is_array($mResult)) {
|
||||
$mResult = array();
|
||||
}
|
||||
$mResult[] = new NextCloudSuggestions();
|
||||
}
|
||||
}
|
||||
|
||||
protected function configMapping() : array
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('save_folder')->SetLabel('Save Folder')
|
||||
->SetDefaultValue('Attachments'),
|
||||
\RainLoop\Plugins\Property::NewInstance('suggestions')->SetLabel('Suggestions')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||
->SetDefaultValue(true)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ class OwnCloudPlugin extends \RainLoop\Plugins\AbstractPlugin
|
|||
const
|
||||
NAME = 'OwnCloud',
|
||||
VERSION = '2.0',
|
||||
CATEGORY = 'Security',
|
||||
CATEGORY = 'Integrations',
|
||||
DESCRIPTION = 'Plugin that adds functionality to integrate with OwnCloud.';
|
||||
|
||||
private static function IsOwnCloud() : bool
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue