Skip to content

Commit 72e026b

Browse files
authored
Merge pull request #4 from dotkernel/initial-release-prep
pre-release changes
2 parents 5b3961f + 3a97011 commit 72e026b

File tree

13 files changed

+230
-41
lines changed

13 files changed

+230
-41
lines changed

.github/workflows/codecov.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
on:
2+
- push
3+
4+
name: Run Codecov checks
5+
6+
jobs:
7+
code-coverage:
8+
name: Code Coverage
9+
10+
runs-on: ${{ matrix.os }}
11+
12+
strategy:
13+
matrix:
14+
os:
15+
- ubuntu-latest
16+
17+
php:
18+
- "8.2"
19+
- "8.3"
20+
- "8.4"
21+
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v3
25+
26+
- name: Install PHP
27+
uses: shivammathur/setup-php@v2
28+
with:
29+
php-version: "${{ matrix.php }}"
30+
coverage: pcov
31+
ini-values: assert.exception=1, zend.assertions=1, error_reporting=-1, log_errors_max_len=0, display_errors=On
32+
tools: composer:v2, cs2pr
33+
34+
- name: Determine composer cache directory
35+
run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV
36+
37+
- name: Cache dependencies installed with composer
38+
uses: actions/cache@v3
39+
with:
40+
path: ${{ env.COMPOSER_CACHE_DIR }}
41+
key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }}
42+
restore-keys: |
43+
php${{ matrix.php }}-composer-
44+
45+
- name: Install dependencies with composer
46+
run: composer install --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
47+
48+
- name: Collect code coverage with PHPUnit
49+
run: vendor/bin/phpunit --colors=always --coverage-clover clover.xml
50+
51+
- name: Send code coverage report to Codecov.io
52+
uses: codecov/codecov-action@v3
53+
with:
54+
token: ${{ secrets.CODECOV_TOKEN }}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: "Continuous Integration"
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
tags:
8+
9+
jobs:
10+
ci:
11+
uses: laminas/workflow-continuous-integration/.github/workflows/continuous-integration.yml@1.x
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
on:
2+
- push
3+
4+
name: Run PHPStan checks
5+
6+
jobs:
7+
mutation:
8+
name: PHPStan ${{ matrix.php }}-${{ matrix.os }}
9+
10+
runs-on: ${{ matrix.os }}
11+
12+
strategy:
13+
matrix:
14+
os:
15+
- ubuntu-latest
16+
17+
php:
18+
- "8.2"
19+
- "8.3"
20+
- "8.4"
21+
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v4
25+
26+
- name: Install PHP
27+
uses: shivammathur/setup-php@v2
28+
with:
29+
php-version: "${{ matrix.php }}"
30+
coverage: pcov
31+
ini-values: assert.exception=1, zend.assertions=1, error_reporting=-1, log_errors_max_len=0, display_errors=On
32+
tools: composer:v2, cs2pr
33+
34+
- name: Determine composer cache directory
35+
run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV
36+
37+
- name: Cache dependencies installed with composer
38+
uses: actions/cache@v4
39+
with:
40+
path: ${{ env.COMPOSER_CACHE_DIR }}
41+
key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }}
42+
restore-keys: |
43+
php${{ matrix.php }}-composer-
44+
45+
- name: Install dependencies with composer
46+
run: composer install --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
47+
48+
- name: Run static analysis with PHPStan
49+
run: vendor/bin/phpstan analyse

.laminas-ci.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"backwardCompatibilityCheck": true
3+
}

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## version ?? - date ??
1+
## Version 0.1 - date 2025-08-18
22

33
Initial tagged release
44

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2020 Apidemia
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 67 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,76 @@
1+
# dot-mail-outlook
2+
3+
Dotkernel's Microsoft Outlook ESMTP email service.
4+
5+
> dot-mail-outlook is a wrapper on top of [dotkernel/dot-mail](https://github.com/dotkernel/dot-mail)
6+
7+
## Badges
8+
9+
![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-mail-outlook)
10+
![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-mail-outlook/0.1)
11+
12+
[![GitHub issues](https://img.shields.io/github/issues/dotkernel/dot-mail-outlook)](https://github.com/dotkernel/dot-mail-outlook/issues)
13+
[![GitHub forks](https://img.shields.io/github/forks/dotkernel/dot-mail-outlook)](https://github.com/dotkernel/dot-mail-outlook/network)
14+
[![GitHub stars](https://img.shields.io/github/stars/dotkernel/dot-mail-outlook)](https://github.com/dotkernel/dot-mail-outlook/stargazers)
15+
[![GitHub license](https://img.shields.io/github/license/dotkernel/dot-mail-outlook)](https://github.com/dotkernel/dot-mail-outlook/blob/0.1/LICENSE.md)
16+
17+
[![Build Static](https://github.com/dotkernel/dot-mail-outlook/actions/workflows/continuous-integration.yml/badge.svg?branch=0.1)](https://github.com/dotkernel/dot-mail-outlook/actions/workflows/continuous-integration.yml)
18+
[![codecov](https://codecov.io/gh/dotkernel/dot-mail-outlook/branch/0.1/graph/badge.svg?token=G51NEHYKD3)](https://codecov.io/gh/dotkernel/dot-mail-outlook)
19+
[![PHPStan](https://github.com/dotkernel/dot-mail-outlook/actions/workflows/static-analysis.yml/badge.svg?branch=0.1)](https://github.com/dotkernel/dot-mail/actions/workflows/static-analysis.yml)
20+
121
## Installation
222

3-
Uses the "client credentials" flow from Microsoft for generating the bearer token:
4-
* https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-client-creds-grant-flow
5-
* https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth
23+
Install `dotkernel/dot-mail-outlook` by executing the following Composer command:
24+
25+
```shell
26+
composer require dotkernel/dot-mail-outlook
27+
```
28+
29+
Register `src/ConfigProvider.php` in `config/config.php` by adding the following line:
30+
31+
```php
32+
\Dot\MailOutlook\ConfigProvider::class,
33+
```
34+
35+
## Configuration
636

737
Copy the `dot-mail-outlook.local` file to your `autoload` folder (or copy its contents to `mail.global.php`) and fill in the relevant information.
838

9-
`Dot-mail` configuration **MUST** use the `esmtp` transport under the `dot_mail.default.transport` key.
39+
```php
40+
<?php
41+
42+
declare(strict_types=1);
43+
44+
$tenant = '';
45+
46+
return [
47+
'xoauth2_outlook' => [
48+
"tokenCacheFile" => '',
49+
"tenant" => $tenant,
50+
"access_code_url" => "https://login.microsoftonline.com/{$tenant}/oauth2/v2.0/token",
51+
"client_id" => '',
52+
"client_secret" => '',
53+
"scope" => 'https://outlook.office.com/.default',
54+
"grant_type" => 'client_credentials',
55+
],
56+
];
57+
```
58+
59+
The `dotkernel/dot-mail` config file should be updated to make sure the necessary options are set:
60+
61+
- `transport` **MUST** be set to under the `dot_mail.default.transport` key.
62+
- `port` **MUST** be set to `587` under the `dot_mail.default.smtp_options.port` key.
63+
- `tls` **MUST** be set to `STARTTLS` under the `dot_mail.default.smtp_options.tls` key.
64+
- `host` **MUST** be one of `smtp-mail.outlook.com` or `smtp.office365.com` under the `dot_mail.default.smtp_options.host` key.
65+
66+
## Additional info
1067

11-
`Dot-mail` configuration **MUST** use the `smtp.office365.com` host under the `dot_mail.default.smtp_options.host` key.
68+
`dotkernel/dot-mail-outlook` makes use of SASL XOAUTH2 mechanism for use with the [SMTP AUTH](https://datatracker.ietf.org/doc/html/rfc4954) command.
1269

13-
> Make sure the port is set to 587
70+
To allow generating the bearer token in the background, without user input required,
71+
`dot-mail-outlook` uses the "client credentials" flow from Microsoft:
1472

15-
`Dot-mail` configuration **MUST** be updated to set `tls` to `STARTTLS` under the `dot_mail.default.smtp_options.tls` key, for the `AUTH XOAUTH` command.
73+
- [Authenticate an IMAP, POP or SMTP connection using OAuth](https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth)
74+
- [Microsoft identity platform and the OAuth 2.0 client credentials flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-client-creds-grant-flow)
1675

17-
Register the `ConfigProvider` in `config/config.php`.
76+
> Make sure to set all relevant permissions, give relevant tenant administrator consent and register the necessary service principals, as described in Microsoft's flow.

composer.json

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
{
22
"name": "dotkernel/dot-mail-outlook",
3-
"version": "0.1",
4-
"type": "plugin",
5-
"description": "Dotkernel Dot-Mail Outlook Plugin",
3+
"type": "library",
4+
"description": "Dotkernel Dot-Mail Outlook ESMTP service.",
65
"license": "MIT",
76
"homepage": "https://github.com/dotkernel/dot-mail-outlook",
87
"keywords": [
98
"dotkernel",
109
"dot-mail",
11-
"symfony",
1210
"esmtp",
11+
"microsoft",
12+
"office365",
13+
"outlook",
14+
"symfony",
15+
"symfony-mailer",
1316
"xoauth2"
1417
],
1518
"authors": [
@@ -24,19 +27,19 @@
2427
"dealerdirect/phpcodesniffer-composer-installer": true
2528
}
2629
},
27-
"minimum-stability": "dev",
2830
"require": {
2931
"ext-curl": "*",
30-
"php": "~8.2.0 || ~8.3.0",
32+
"php": "~8.2.0 || ~8.3.0 || ~8.4.0",
3133
"dotkernel/dot-dependency-injection": "^1.2.0",
3234
"dotkernel/dot-mail": "^5.1.5",
33-
"laminas/laminas-servicemanager": "^3.22",
35+
"laminas/laminas-servicemanager": "^3.22 || ^4.0",
3436
"symfony/mailer": "^v7.1.6"
3537
},
3638
"require-dev": {
3739
"laminas/laminas-coding-standard": "^3.1.0",
38-
"phpunit/phpunit": "^10.5.46",
39-
"vimeo/psalm": "^5.23"
40+
"phpstan/phpstan": "^2.1",
41+
"phpstan/phpstan-phpunit": "^2.0",
42+
"phpunit/phpunit": "^10.5.46"
4043
},
4144
"autoload": {
4245
"psr-4": {
@@ -56,7 +59,7 @@
5659
],
5760
"cs-check": "phpcs",
5861
"cs-fix": "phpcbf",
59-
"static-analysis": "psalm --shepherd --stats",
62+
"static-analysis": "phpstan analyse --memory-limit 1G",
6063
"test": "phpunit --colors=always"
6164
}
6265
}

config/dot-mail-outlook.local.php.dist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ $tenant = '';
66

77
return [
88
'xoauth2_outlook' => [
9-
"tokenCacheFile" => '', // actual Bearer token
9+
"tokenCacheFile" => '',
1010
"tenant" => $tenant,
1111
"access_code_url" => "https://login.microsoftonline.com/{$tenant}/oauth2/v2.0/token",
1212
"client_id" => '',

phpstan.neon

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
includes:
2+
- vendor/phpstan/phpstan-phpunit/extension.neon
3+
parameters:
4+
level: 5
5+
paths:
6+
- src
7+
- test
8+
treatPhpDocTypesAsCertain: false

0 commit comments

Comments
 (0)