Skip to content

Commit 44e5775

Browse files
committed
Merge branch 'main' into build
2 parents bd5819a + 6fc3347 commit 44e5775

File tree

6 files changed

+221
-117
lines changed

6 files changed

+221
-117
lines changed

.github/workflows/build.yml

+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
name: Add built assets to latest release
2+
3+
on:
4+
push:
5+
6+
permissions:
7+
contents: write
8+
9+
jobs:
10+
get_tag:
11+
# get the latest tag (separate job as Windows doesn't support this method)
12+
# straightforward because in this repository tags are used only for releases, but we could do a regex match if not
13+
runs-on: ubuntu-latest
14+
outputs:
15+
output: ${{ steps.latest_tag.outputs.tag }}
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
- id: latest_tag
20+
run: |
21+
git fetch -a
22+
echo "tag=$(git tag --sort -committerdate | head -n 1)" >> $GITHUB_OUTPUT
23+
24+
build:
25+
needs: get_tag
26+
27+
runs-on: ${{ matrix.os }}
28+
strategy:
29+
fail-fast: false
30+
matrix:
31+
os: [macos-latest, windows-latest]
32+
33+
steps:
34+
- uses: actions/checkout@v4
35+
- uses: actions/setup-python@v5
36+
with:
37+
python-version: '3.x'
38+
39+
# install requirements
40+
# - note: `imageio` is required here to convert our PNG icon to a format nuitka can handle (nuitka itself is a separate action)
41+
# - note: `certifi` is required here because pyinstaller no longer bundles certificates (pyinstaller #7229)
42+
# - note: `boto3`, `requests`, `google-auth` and corresponding pyinstaller hidden imports / nuitka included
43+
# packages are so that advanced proxy features work in pre-built binaries
44+
# - note: `--hidden-import timeago.locales.en_short` is required for GUI mode until `timeago` #40 is fixed
45+
- run: |
46+
python -m pip install --upgrade pip
47+
python -m pip install wheel
48+
python -m pip install pyinstaller imageio
49+
python -m pip install -r requirements-core.txt -r requirements-gui.txt
50+
python -m pip install certifi
51+
python -m pip install boto3 requests google-auth
52+
53+
# build the pyinstaller version (same method for both macOS and Windows), outputting to the folder `dist`
54+
- run: python -m PyInstaller --clean --noconsole --onefile --hidden-import prompt_toolkit --hidden-import timeago.locales.en_short --hidden-import certifi --hidden-import boto3 --hidden-import requests --hidden-import google --hidden-import jwt --icon icon.png --distpath dist/ emailproxy.py
55+
56+
# add license, documentation, configuration file sample and disclaimer
57+
# - note: `move [...] alias move=mv [...]` is to support using the same commands on all platforms
58+
- run: |
59+
move LICENSE . 2> nul || { shopt -s expand_aliases; alias move=mv; }
60+
move LICENSE dist/
61+
move README.md dist/
62+
move emailproxy.config dist/
63+
echo 'This binary distribution is automatically created for each Email OAuth 2.0 Proxy release, ' >> _.txt
64+
echo 'but is not tested, and is not officially supported. Using the main emailproxy.py script ' >> _.txt
65+
echo 'directly is recommended for best results: https://github.com/simonrob/email-oauth2-proxy/' >> _.txt
66+
move _.txt dist/GettingStarted.txt
67+
68+
# on macOS pyinstaller `--onefile` creates bundle *and* binary; we don't need both (and the .app also contains the binary)
69+
- if: runner.os == 'macOS'
70+
run: rm dist/emailproxy
71+
72+
# zip the built pyinstaller output, naming according to tag and OS
73+
- uses: thedoctor0/[email protected]
74+
with:
75+
type: zip
76+
directory: dist/
77+
filename: emailproxy-${{ needs.get_tag.outputs.output }}_pyinstaller-${{ runner.os }}.zip
78+
79+
# append the pyinstaller zip to the latest release
80+
- uses: xresloader/[email protected]
81+
with:
82+
file: dist/*.zip
83+
update_latest_release: true
84+
85+
# clean up pyinstaller assets and add platform-specific nuitka configuration options (`move` alias usage as above)
86+
- run: |
87+
rm dist/emailproxy-${{ needs.get_tag.outputs.output }}_pyinstaller-${{ runner.os }}.zip
88+
move emailproxy.py . 2> nul || { shopt -s expand_aliases; alias move=mv; }
89+
move emailproxy.py _.py
90+
echo '# nuitka-project-if: {OS} in ("Windows"):' >> _.txt
91+
echo '# nuitka-project: --windows-icon-from-ico=icon.png' >> _.txt
92+
echo '# nuitka-project-if: {OS} == "Darwin":' >> _.txt
93+
echo '# nuitka-project: --macos-app-icon=icon.png' >> _.txt
94+
move _.txt emailproxy.py
95+
cat _.py >> emailproxy.py
96+
97+
# build the nuitka version - by default, this uses the options `--mode=app --assume-yes-for-downloads --output-dir=build` (see: https://github.com/Nuitka/Nuitka-Action/blob/main/action.yml)
98+
- uses: Nuitka/Nuitka-Action@main
99+
with:
100+
nuitka-version: main
101+
script-name: emailproxy.py
102+
include-package: |
103+
prompt_toolkit
104+
timeago.locales.en_short
105+
certifi
106+
boto3
107+
requests
108+
google
109+
jwt
110+
nofollow-import-to: '*.tests'
111+
112+
# replace previous build files (-f vs. -fo behaviour differences mean we can't combine); add macOS quarantine tips
113+
- if: runner.os == 'macOS'
114+
run: |
115+
rm -rf dist/emailproxy.app/
116+
echo "\nIf macOS says the app is damaged, run `xattr -dr com.apple.quarantine emailproxy.app`" >> dist/GettingStarted.txt
117+
echo 'If you still have problems, try no-GUI mode: `emailproxy.app/Contents/MacOS/emailproxy --no-gui`' >> dist/GettingStarted.txt
118+
mv build/emailproxy.app/ dist/
119+
120+
- if: runner.os == 'Windows'
121+
run: |
122+
rm dist/emailproxy.exe
123+
move build/emailproxy.exe dist/
124+
125+
# zip the built nuitka output, naming according to tag and OS
126+
- uses: thedoctor0/[email protected]
127+
with:
128+
type: zip
129+
directory: dist/
130+
filename: emailproxy-${{ needs.get_tag.outputs.output }}_nuitka-${{ runner.os }}.zip
131+
132+
# append the nuitka zip to the latest release
133+
- uses: xresloader/[email protected]
134+
with:
135+
file: dist/*.zip
136+
update_latest_release: true

.github/workflows/pyinstaller.yml

-81
This file was deleted.

README.md

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
11
# Email OAuth 2.0 Proxy<a id="email-oauth-20-proxy"></a>
22
Transparently add OAuth 2.0 support to IMAP/POP/SMTP client applications, scripts or any other email use-cases that don't support this authentication method.
33

4+
<div align="center">
5+
<br><strong>Email OAuth 2.0 Proxy is sponsored by</strong><br><br>
6+
<a href="https://auth-email.com/?ref=emailproxy">
7+
<picture>
8+
<source width="300" media="(prefers-color-scheme: dark)" srcset="https://auth-email.com/static/img/logo-full-dark.svg">
9+
<source width="300" media="(prefers-color-scheme: light)" srcset="https://auth-email.com/static/img/logo-full-light.svg">
10+
<img width="300" src="https://auth-email.com/static/img/logo-full.png" alt="Email-Auth logo">
11+
</picture><br>
12+
<b>Email OAuth made simple</b><br>
13+
<sub>Auth-Email.com is a unified proxy for all your OAuth 2.0 email accounts.</sub><br>
14+
<sup>Use any app or client to access your accounts with ease.</sup>
15+
</a><br><br>
16+
</div>
17+
418

519
## Motivation and capabilities<a id="motivation-and-capabilities"></a>
620
Email services that support IMAP, POP and/or SMTP access are increasingly requiring the use of OAuth 2.0 to authenticate connections, but not all clients support this method.
7-
This tool creates a simple local proxy that intercepts the traditional IMAP/POP/SMTP authentication commands and transparently replaces them with the appropriate SASL (X)OAuth 2.0 commands and credentials.
21+
This tool creates a local proxy that intercepts the traditional IMAP/POP/SMTP authentication commands and transparently replaces them with the appropriate SASL (X)OAuth 2.0 commands and credentials.
822
Your email client can continue to use the `login` or `auth`/`authenticate` options, with no need to make it aware of OAuth's existence.
923
The proxy works in the background with a menu bar/taskbar helper or as a headless system service, and is compatible with macOS, Windows and Linux.
1024

@@ -194,7 +208,7 @@ Please [open an issue](https://github.com/simonrob/email-oauth2-proxy/issues) if
194208

195209
When first launching on Linux in GUI mode you may encounter errors similar to `Namespace […] not available`, issues with the task bar icon display, or no browser popup when attempting to authorise your accounts.
196210
This is caused by missing dependencies for [pystray](https://github.com/moses-palmer/pystray/) and [pywebview](https://github.com/r0x0r/pywebview/), which are used to display the menu bar icon and authentication windows.
197-
See the [pywebview dependencies](https://pywebview.flowrl.com/guide/installation.html#dependencies) and [pystray FAQ](https://pystray.readthedocs.io/en/latest/faq.html) pages and [existing](https://github.com/simonrob/email-oauth2-proxy/issues/1#issuecomment-831746642) [closed issues](https://github.com/simonrob/email-oauth2-proxy/issues/136#issuecomment-1430417456) in this repository for a summary and suggestions about how to resolve this.
211+
See the [pywebview dependencies](https://pywebview.flowrl.com/guide/installation.html#dependencies) and [pystray FAQ](https://pystray.readthedocs.io/en/latest/faq.html) pages and [existing](https://github.com/simonrob/email-oauth2-proxy/issues/1#issuecomment-831746642) [closed](https://github.com/simonrob/email-oauth2-proxy/issues/136#issuecomment-1430417456) [issues](https://github.com/simonrob/email-oauth2-proxy/issues/305#issuecomment-2482989955) in this repository for a summary and suggestions about how to resolve this.
198212

199213
A similar issue may occur on Windows with the [pythonnet](https://github.com/pythonnet/pythonnet) package, which is required by [pywebview](https://github.com/r0x0r/pywebview).
200214
The [pythonnet installation instructions](https://github.com/pythonnet/pythonnet/wiki/Installation) may offer alternative ways to install this package if the default installation fails.
@@ -206,6 +220,9 @@ On Windows this is normally limited to keyboard shortcuts (i.e., copy/paste), bu
206220
As a workaround, the proxy will enable pywebview's debug mode when you run the proxy itself in debug mode, which should allow you to use the right-click context menu to copy/paste to enter text.
207221
If you are unable to proceed with popup-based authentication even with this workaround, it is worth trying the proxy's `--external-auth` or `--local-server-auth` options.
208222

223+
- If the authorisation window fails to render due to an issue with hardware acceleration (for example: `MESA: error: ZINK: failed to choose pdev`), you can try disabling hardware rendering by setting the environment variable `LIBGL_ALWAYS_SOFTWARE=1`.
224+
You may also wish to try disabling the DMABUF renderer in WebKit with `WEBKIT_DISABLE_DMABUF_RENDERER=1`.
225+
209226
- On macOS (10.14 and later), you may find that when first running the proxy as a service you need to manually load its launch agent in order to trigger a file access permission prompt.
210227
You will know intervention is necessary if the proxy exits (rather than restarts) the first time you click `Start at login` from its menu bar icon.
211228
To resolve this, exit the proxy and then run `launchctl load ~/Library/LaunchAgents/ac.robinson.email-oauth2-proxy.plist` from a terminal.

emailproxy.config

+5-3
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,12 @@ documentation = Accounts are specified using your email address as the section h
166166
attempts before the first valid login, pre-encrypting account entries is highly recommended. See the example
167167
script at https://github.com/simonrob/email-oauth2-proxy/issues/61#issuecomment-1259110336.
168168

169-
- The proxy supports the device authorisation grant (DAG) OAuth 2.0 flow, which may better suit headless systems
170-
(currently only known to be available for Office 365 / Outlook). To use this flow, set `oauth2_flow = device`. With
169+
- The proxy supports the device authorisation grant (DAG) OAuth 2.0 flow (currently only known to be available for
170+
Office 365 / Outlook), which may better suit headless systems. To use this flow, set `oauth2_flow = device`. With
171171
this flow, the proxy receives authorisation responses directly from the service provider, so no `redirect_uri` is
172-
needed. An example account configuration is given below.
172+
needed. An example account configuration is given below. For additional customisation, the proxy modifications and
173+
scripts demonstrated at https://github.com/simonrob/email-oauth2-proxy/pull/317 show how the DAG flow authorisation
174+
message could be pushed to a separate device, which may be useful when running the proxy headless or without a GUI.
173175

174176
Gmail customisation:
175177
- The proxy supports the use of service accounts with Gmail for Google Workspace (note: normal Gmail accounts do not

0 commit comments

Comments
 (0)