Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
217 commits
Select commit Hold shift + click to select a range
56b2dc4
Split Auth class to support multiple providers
Sep 2, 2017
eb62329
ACL Support
May 5, 2018
9b07b97
Add OAuth2 client support
May 5, 2018
fbe68df
Release 0.2
May 5, 2018
fb4eeb8
Add credentials table
Feb 17, 2019
776aa36
Cleanup, fix tests
Feb 17, 2019
2f2a75d
Include mysql_testcase only once
Feb 17, 2019
a1d728b
Use require_once for Mysql_TestCase
Feb 17, 2019
bc5d00e
updates
Apr 7, 2019
6efcc47
OAuthController: Support https behind proxy
May 19, 2019
5b652c2
fixup OAuthController header name
May 19, 2019
72c1a5c
fix: return proper Forbidden code
GuilhermeBarile Apr 19, 2025
46f5ffc
fix: allow unauthenticated users to see /index
GuilhermeBarile Apr 19, 2025
24a7cc7
fixes
GuilhermeBarile May 17, 2025
4c218e8
feat: Add RequireRole Middleware
GuilhermeBarile Sep 29, 2025
0afed19
feat: replace AclTrait with RequireRole Attribute
GuilhermeBarile Oct 12, 2025
b735d5d
fix: use array
GuilhermeBarile Oct 12, 2025
2945179
Use DI to instantiate RequireRole
GuilhermeBarile Dec 21, 2025
ad5c296
Update Middleware syntax
GuilhermeBarile Dec 22, 2025
fa60536
Use RequireScope Middleware for consistency
GuilhermeBarile Dec 29, 2025
a8fabd4
fix: Test auth before fetching the user in user_can
GuilhermeBarile Jan 3, 2026
acfad6e
Update dependencies
GuilhermeBarile Feb 25, 2026
be2c8cd
Security Improvements
GuilhermeBarile Feb 25, 2026
9a2d425
Replace MysqlAuth with DBAuth
GuilhermeBarile Feb 25, 2026
a2fb09c
Replace travis with github action
GuilhermeBarile Feb 25, 2026
470edff
Security improvements
GuilhermeBarile Feb 25, 2026
146cba6
Add user_roles support
GuilhermeBarile Feb 25, 2026
54635e2
Replace `with` functionality with `relations`
GuilhermeBarile Feb 25, 2026
00de2fb
Fix Middleware types
GuilhermeBarile Mar 3, 2026
1d9438f
Add login_providers support, add credentials list to user
GuilhermeBarile Mar 4, 2026
f1af342
Rework Scope/Roles
GuilhermeBarile Mar 15, 2026
a6dac1f
fix: last login/roles hydration
GuilhermeBarile Mar 15, 2026
e520385
feat: get_users_by_role
GuilhermeBarile Mar 15, 2026
8e920d3
Add get_roles
GuilhermeBarile Mar 23, 2026
e87b626
Add reusable user management API
GuilhermeBarile Jul 25, 2026
37f41f1
Keep new credentials marked as never logged in
GuilhermeBarile Jul 25, 2026
224dfc4
Honor database prefix when resetting passwords
GuilhermeBarile Jul 28, 2026
10c68bd
Lock objectiveweb/db to 0.8.x
objectivebot Sep 27, 2026
4ba276f
Harden OAuth session establishment
objectivebot Sep 27, 2026
b635632
Harden OAuth session establishment
objectivebot Sep 27, 2026
88921e2
Test OAuth session security
objectivebot Sep 27, 2026
7b4c91b
Align 0.2.0 DBAuth documentation
objectivebot Sep 27, 2026
0531420
Add Phinx CI configuration
objectivebot Sep 27, 2026
74c277f
Strengthen 0.2.0 release CI
objectivebot Sep 27, 2026
573f1e8
Centralize public user sanitization
objectivebot Sep 28, 2026
65462ba
Sanitize DBAuth public user results
objectivebot Sep 28, 2026
ae1e4b5
Use canonical user sanitization in BasicAuth
objectivebot Sep 28, 2026
7294c03
Test public user secret sanitization
objectivebot Sep 28, 2026
95fc5f2
Scope eager relations to subject user
objectivebot Sep 28, 2026
e384322
Test eager relation subject isolation
objectivebot Sep 28, 2026
34f859d
Include lifecycle state in role user queries
objectivebot Sep 28, 2026
d5fb61c
Test final active admin lifecycle guard
objectivebot Sep 28, 2026
9c0539c
Align auth migration with DBAuth defaults
objectivebot Sep 28, 2026
9abd7e7
Verify migrated auth schema
objectivebot Sep 28, 2026
6741afb
Verify DBAuth migration schema in CI
objectivebot Sep 28, 2026
2db85c4
Align controller test schema with auth defaults
objectivebot Sep 28, 2026
2063e6b
Make role user lookup database portable
objectivebot Sep 28, 2026
907724e
Keep role lookup results public-safe
objectivebot Sep 28, 2026
5e9bea7
Test role lookup on PostgreSQL
objectivebot Sep 28, 2026
a2225dd
Exercise role lookup on PostgreSQL
objectivebot Sep 28, 2026
457a77b
Align BasicAuth provider semantics
objectivebot Sep 28, 2026
1d85eb3
Test BasicAuth provider parity
objectivebot Sep 28, 2026
0ec48cb
Tighten user management input validation
objectivebot Sep 28, 2026
9ef9221
Test user management input validation
objectivebot Sep 28, 2026
80f643b
Harden and test OAuth callback flow
objectivebot Sep 28, 2026
c82fe47
Keep OAuth redirect flow void-safe
objectivebot Sep 28, 2026
9519b91
Add OAuth provider test fixture
objectivebot Sep 28, 2026
204615b
Expand OAuth callback and linking tests
objectivebot Sep 28, 2026
cb46432
Document explicit OAuth redirect URI
objectivebot Sep 28, 2026
da445cc
Consume OAuth state safely
objectivebot Sep 28, 2026
25fe76a
Add router 3.x dev dependency
objectivebot Oct 1, 2026
01ea516
Allow router 3.0 and newer
objectivebot Oct 1, 2026
46c188f
Use router 3.x compatibility constraint
objectivebot Oct 1, 2026
726a4ad
Optimize user queries and reset token lookup
objectivebot Oct 1, 2026
38ddbb9
Preserve unassigned role query semantics
objectivebot Oct 1, 2026
1418e1a
Index reset token digests
objectivebot Oct 1, 2026
f3f7629
Verify reset token index
objectivebot Oct 1, 2026
3086bdd
Test paginated queries and reset token digests
objectivebot Oct 1, 2026
46b1344
Document indexed reset token digests
objectivebot Oct 1, 2026
146c4eb
Match Router 3 middleware contract
objectivebot Oct 1, 2026
90eb7a3
Restore DBAuth UUID generation
objectivebot Oct 1, 2026
3c30e97
Use Table collections for DBAuth queries
objectivebot Oct 1, 2026
22d7855
Return Collection from BasicAuth queries
objectivebot Oct 1, 2026
828dc8b
Define Collection query contract
objectivebot Oct 1, 2026
783af4a
Return user Collections directly
objectivebot Oct 1, 2026
897f410
Test DBAuth Collection query results
objectivebot Oct 1, 2026
7477791
Test user controller Collection responses
objectivebot Oct 1, 2026
cf393c7
Test BasicAuth Collection pagination
objectivebot Oct 1, 2026
80aafa3
Document Collection query responses
objectivebot Oct 1, 2026
40b8f01
Fix BasicAuth Collection sort expectation
objectivebot Oct 1, 2026
62b4f7c
Verify Collection queries on PostgreSQL
objectivebot Oct 1, 2026
b3ed974
Reuse user Table across DBAuth
objectivebot Oct 1, 2026
6444c27
Clarify low-level OR candidate scans
objectivebot Oct 1, 2026
a8dee0b
Test user Table alternate-key lookup
objectivebot Oct 1, 2026
a2bd069
Run push CI only on master
objectivebot Oct 1, 2026
8acaa3a
Add master release verification workflow
objectivebot Oct 1, 2026
a657fdf
Prevent password recovery account enumeration
objectivebot Oct 1, 2026
56c7bd4
Test recovery enumeration protection
objectivebot Oct 1, 2026
c86ca52
Document recovery enumeration protection
objectivebot Oct 1, 2026
31a86b8
Add provider password verification for authenticated changes
objectivebot Oct 4, 2026
e620333
Require current password and session CSRF for password changes
objectivebot Oct 4, 2026
ec93c84
Cover authenticated password verification and CSRF
objectivebot Oct 4, 2026
d48fe05
Verify DBAuth password changes with current password
objectivebot Oct 4, 2026
60586a3
Document secure authenticated password change flow
objectivebot Oct 4, 2026
f3c71d2
Reorganize DBAuth setup, parameters, user credentials, roles and rela…
objectivebot Oct 4, 2026
fccb70b
Restore copyable default SQLite schema in DBAuth documentation
objectivebot Oct 4, 2026
5a874a9
Load application-defined user context when establishing and refreshin…
objectivebot Oct 4, 2026
21f0a8e
Remove app-owned managed relation persistence from DBAuth
objectivebot Oct 4, 2026
570b6b1
Remove application managed relations from BasicAuth
objectivebot Oct 4, 2026
cffa18d
Keep application association writes out of Auth user-management API
objectivebot Oct 4, 2026
a7ecdfa
Test callback session hydration, refresh and invalid payload behavior
objectivebot Oct 4, 2026
dbc1ba0
Replace managed-relations tests with DB session context and app owner…
objectivebot Oct 4, 2026
8e17079
Ensure generic user controller rejects app relation payloads
objectivebot Oct 4, 2026
1d7e8c8
Document application-owned associations and session context callback
objectivebot Oct 4, 2026
465bca9
Avoid fixed autoincrement ID assumption in user controller test
objectivebot Oct 4, 2026
c800feb
Restrict logout redirects to same-origin paths
objectivebot Oct 4, 2026
2459d78
Test logout redirect open-redirect protection
objectivebot Oct 4, 2026
ba53ddb
fix(auth): only allow local credentials in public registration
objectivebot Oct 19, 2026
c058c23
test(auth): cover provider injection and role grants on signup
objectivebot Oct 19, 2026
1882516
docs(auth): explain local-only public registration trust boundary
objectivebot Oct 19, 2026
29fb91f
feat(auth): define per-credential proof and verification contract
objectivebot Oct 19, 2026
4170133
feat(auth): add independent credential verification timestamps and ex…
objectivebot Oct 19, 2026
74bc0b0
feat(auth): hash and consume verification tokens per DB credential
objectivebot Oct 19, 2026
56f2372
feat(auth): implement independent verification tokens for BasicAuth
objectivebot Oct 19, 2026
997af5b
fix(auth): bind OAuth logins only to provider-verified credential ide…
objectivebot Oct 19, 2026
12cd59b
test(auth): prove OAuth email collision and pending-association isola…
objectivebot Oct 19, 2026
21503e3
test(auth): align credential verification state and schema across pro…
objectivebot Oct 19, 2026
ef2135d
test(auth): align credential verification state and schema across pro…
objectivebot Oct 19, 2026
47be4b6
test(auth): align credential verification state and schema across pro…
objectivebot Oct 19, 2026
71557c7
test(auth): align credential verification state and schema across pro…
objectivebot Oct 19, 2026
fb6dcbd
test(auth): align credential verification state and schema across pro…
objectivebot Oct 19, 2026
d8476e9
test(auth): align credential verification state and schema across pro…
objectivebot Oct 19, 2026
95d1d24
feat(auth): expose one-time credential confirmation without account l…
objectivebot Oct 19, 2026
e093216
fix(auth): require independent proof for contact credentials, OAuth p…
objectivebot Oct 19, 2026
2f6b9eb
fix(auth): require independent proof for contact credentials, OAuth p…
objectivebot Oct 19, 2026
60556d5
fix(auth): require independent proof for contact credentials, OAuth p…
objectivebot Oct 19, 2026
59da18e
test(auth): exercise independent hashed credential tokens and replay …
objectivebot Oct 19, 2026
63d8696
test(auth): verify SQLite token isolation, expiry, ownership and rena…
objectivebot Oct 19, 2026
102ac7c
test(auth): cover credential token redemption without session establi…
objectivebot Oct 19, 2026
14fef66
docs(auth): describe individual credential proof tokens and secure OA…
objectivebot Oct 19, 2026
8665df2
fix(auth): keep BasicAuth raw credential verification fields consiste…
objectivebot Oct 19, 2026
eccdd48
fix(auth): atomically consume password-reset tokens using conditional…
objectivebot Oct 19, 2026
6713e30
test(auth): assert atomic reset consumption under interleaving reques…
objectivebot Oct 19, 2026
10ba8eb
fix(tests): correct Closure callback type in interleaving reset checks
objectivebot Oct 19, 2026
177072f
fix(auth): normalize password login failures without rate limiting
objectivebot Oct 20, 2026
8707ac7
fix(auth): bind OAuth state to provider/session and use PKCE S256
objectivebot Oct 20, 2026
d4adf7f
test(auth): verify PKCE options reach OAuth authorization/token provider
objectivebot Oct 20, 2026
3ad02ef
test(auth): cover provider-bound state, PKCE, expiry, replay and sess…
objectivebot Oct 20, 2026
efafd15
fix(auth): maintain consistent login errors with regression tests
objectivebot Oct 20, 2026
32e6dcc
fix(auth): maintain consistent login errors with regression tests
objectivebot Oct 20, 2026
5fb9c26
fix(auth): maintain consistent login errors with regression tests
objectivebot Oct 20, 2026
657f590
fix(auth): maintain consistent login errors with regression tests
objectivebot Oct 20, 2026
327ee80
test(auth): add second OAuth mock provider for state isolation
objectivebot Oct 20, 2026
4b5300d
docs(auth): explain generic login errors, OAuth PKCE and deferred thr…
objectivebot Oct 20, 2026
563727d
fix(auth): separate explicit CSRF-protected OAuth linking from ordina…
objectivebot Oct 20, 2026
66f5d77
test(auth): cover explicit OAuth link flow, CSRF, login isolation and…
objectivebot Oct 20, 2026
5196e3c
feat(auth): return OAuth linking authorization URL from JSON POST
objectivebot Oct 20, 2026
a86c1cb
test(auth): assert JSON-based OAuth link initiation contract
objectivebot Oct 20, 2026
c23ef78
docs(auth): document explicit CSRF-protected OAuth account linking flow
objectivebot Oct 20, 2026
99ca1c4
feat(auth): require explicit account choice after first-time OAuth au…
objectivebot Oct 20, 2026
b2bee71
refactor(auth): share registration authorization with OAuth account c…
objectivebot Oct 20, 2026
98a6b72
test(auth): verify OAuth account choice prevents duplicates and suppo…
objectivebot Oct 20, 2026
22c00fd
test(auth): cover pending OAuth expiry, replay, registration policy, …
objectivebot Oct 20, 2026
1335fe8
feat(auth): add reusable account-choice page for first-time OAuth login
objectivebot Oct 20, 2026
ebf12e9
docs(auth): document first-time OAuth account choice and account-link…
objectivebot Oct 20, 2026
d64086a
test(auth): match anonymous registration scope denial status
objectivebot Oct 20, 2026
fa32e3d
test(auth): exercise OAuth existing-account choice against SQLite DBAuth
objectivebot Oct 20, 2026
9ef9d9a
test(auth): fix SQLite account-choice assertion and preserve test order
objectivebot Oct 20, 2026
bb5eaef
fix(auth): normalize optional OAuth resource-owner profile fields safely
objectivebot Oct 20, 2026
ed255cb
test(auth): cover minimal League resource owners and safe OAuth profi…
objectivebot Oct 20, 2026
6bf98db
docs(auth): document League resource-owner compatibility and safe pro…
objectivebot Oct 20, 2026
94222f4
test(auth): keep League OAuth2 optional while testing minimal resourc…
objectivebot Oct 20, 2026
ba2f362
fix(auth): require explicitly configured trusted OAuth callback URI
objectivebot Oct 20, 2026
07723f1
test(auth): reject request-derived and unsafe callback URLs; allow ex…
objectivebot Oct 20, 2026
0a14726
docs(auth): require trusted configured callback URI and document loop…
objectivebot Oct 20, 2026
9afe5a0
refactor(auth): allow injecting real OAuth provider HTTP collaborator…
objectivebot Oct 20, 2026
7c4c08b
test(auth): exercise real Google and Facebook OAuth providers with mo…
objectivebot Oct 20, 2026
7f8e931
ci(auth): run real Google/Facebook OAuth integration using optional p…
objectivebot Oct 20, 2026
4acaa08
test(auth): assert provider-specific OAuth token endpoint paths
objectivebot Oct 20, 2026
2898571
docs(auth): document real-provider OAuth integration tests and CI lim…
objectivebot Oct 20, 2026
39dea86
test(auth): cover real-provider returning login and explicit Facebook…
objectivebot Oct 20, 2026
9693046
ci(auth): add dedicated MySQL Phinx migration environment
objectivebot Oct 20, 2026
0dfc8b2
test(auth): verify MySQL migration schema, indexes and foreign keys
objectivebot Oct 20, 2026
a70ab66
test(auth): exercise DBAuth authentication and verification workflows…
objectivebot Oct 20, 2026
869e193
ci(auth): test MySQL 8.0/8.4 migrations and DBAuth flows
objectivebot Oct 20, 2026
8e4b838
docs(auth): document MySQL 8.0/8.4 CI and local migration checks
objectivebot Oct 20, 2026
a370893
fix(auth): declare credential composite primary key columns NOT NULL …
objectivebot Oct 20, 2026
c94096e
fix(auth): declare role and delegation composite-key columns NOT NULL…
objectivebot Oct 20, 2026
c1d6baa
test(auth): add standalone no-dev production-install smoke test
objectivebot Oct 20, 2026
1088a7a
ci(auth): gate PR on no-dev production install and isolated consumer …
objectivebot Oct 20, 2026
18b3302
docs(auth): describe pre-merge production and consumer install verifi…
objectivebot Oct 20, 2026
29effdb
docs(auth): add v0.2.0 changelog and breaking change summary
objectivebot Oct 20, 2026
c0ec2cf
docs(auth): add practical 0.1.x to 0.2.0 upgrade guide and rollout ch…
objectivebot Oct 20, 2026
81a140c
docs(auth): correct Markdown formatting in 0.2 upgrade guide
objectivebot Oct 20, 2026
6abc637
docs(auth): prepare v0.2.0 release notes and operator checklist
objectivebot Oct 20, 2026
feabae8
docs(auth): link v0.2 release guides and fix SQLite credential schema…
objectivebot Oct 20, 2026
cf17c72
refactor(auth): validate credentials without starting a session
objectivebot Oct 20, 2026
1f3c32a
fix(oauth): authenticate only after linking existing account succeeds
objectivebot Oct 20, 2026
64ba93f
test(oauth): linking failure must not establish authenticated session
objectivebot Oct 20, 2026
da6ebe2
docs(auth): consolidate credential validation method documentation
objectivebot Oct 20, 2026
94fbaf6
fix(auth): reject tokens expiring during credential redemption
objectivebot Oct 20, 2026
8059ef0
test(auth): reject token expiry races during credential verification
objectivebot Oct 20, 2026
96eb27f
fix(auth): prevent recovery callback errors from leaking reset secret…
objectivebot Oct 20, 2026
eaa2b80
test(auth): ensure recovery delivery logs redact reset tokens and rec…
objectivebot Oct 20, 2026
f898ff9
fix(auth): atomically update user fields and role assignments
objectivebot Oct 20, 2026
d14caff
fix(auth): restrict relation cleanup to explicitly Auth-owned tables
objectivebot Oct 20, 2026
255bb3b
fix(auth): revalidate session before all user_can decisions
objectivebot Oct 20, 2026
aeaaddc
fix(auth): reject unexpected user deletion subresources
objectivebot Oct 21, 2026
237da9c
fix(auth): preserve BasicAuth credential profiles on login
objectivebot Oct 21, 2026
ce809fe
fix(auth): enforce exact MySQL OAuth credential identity matching
objectivebot Oct 21, 2026
e3799e9
fix(auth): require verified recovery credentials before issuing reset…
objectivebot Oct 22, 2026
81f10b9
fix(auth): revoke outstanding reset tokens on password changes
objectivebot Oct 22, 2026
1229181
fix(auth): serialize final active admin checks and mutations
objectivebot Oct 22, 2026
c319d76
test(auth): establish management actor sessions for admin guard regre…
objectivebot Oct 22, 2026
a6239cf
refactor(auth): enforce final-admin invariant in DBAuth update and de…
objectivebot Oct 23, 2026
3c8809f
test(auth): preserve a backup active admin in session revocation tests
objectivebot Oct 23, 2026
74f7e69
test(auth): preserve backup admin in MySQL role replacement smoke test
objectivebot Oct 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 176 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
name: CI

on:
push:
branches:
- master
pull_request:

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php-version: ["8.2", "8.3", "8.4", "8.5"]

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
coverage: none

- name: Validate Composer metadata
run: composer validate --strict

- name: Install dependencies
run: composer install --no-interaction --prefer-dist

- name: Run tests
run: vendor/bin/phpunit test

oauth-real-providers:
# Validate integration using the actual optional League provider classes
# without sending requests to Google/Facebook or requiring live secrets.
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.4"
coverage: none

- name: Install test dependencies
run: composer install --no-interaction --prefer-dist

- name: Install optional OAuth provider libraries for integration tests
run: |
composer require --dev --no-interaction --prefer-dist --no-progress \
'league/oauth2-google:^4.0' \
'league/oauth2-facebook:^2.0' \
'guzzlehttp/guzzle:^7.0'

- name: Assert real OAuth providers are available
run: |
php -r 'require "vendor/autoload.php"; exit(
class_exists("League\\OAuth2\\Client\\Provider\\Google") &&
class_exists("League\\OAuth2\\Client\\Provider\\Facebook") ? 0 : 1
);'

- name: Run real-provider OAuth integration tests
run: vendor/bin/phpunit test/RealOAuthProviderTest.php

migrations-mysql:
name: MySQL ${{ matrix.mysql-version }} migrations and DBAuth
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
mysql-version: ["8.0", "8.4"]

services:
mysql:
image: mysql:${{ matrix.mysql-version }}
env:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: auth_test
MYSQL_USER: auth_user
MYSQL_PASSWORD: auth_password
ports:
- 3306:3306
options: >-
--health-cmd="mysqladmin ping --host=127.0.0.1 --user=auth_user --password=auth_password --silent"
--health-interval=10s
--health-timeout=5s
--health-retries=10

env:
MYSQL_HOST: 127.0.0.1
MYSQL_PORT: 3306
MYSQL_DATABASE: auth_test
MYSQL_USER: auth_user
MYSQL_PASSWORD: auth_password

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.4"
extensions: pdo_mysql
coverage: none

- name: Install dependencies
run: composer install --no-interaction --prefer-dist

- name: Run bundled Phinx migrations on MySQL
run: vendor/bin/phinx migrate --configuration test/phinx.php --environment mysql_testing

- name: Verify MySQL migration status
run: vendor/bin/phinx status --configuration test/phinx.php --environment mysql_testing

- name: Verify MySQL schema, indexes and foreign keys
run: php test/verify_mysql_migrations.php

- name: Verify MySQL DBAuth authentication workflows
run: php test/verify_mysql_auth.php

migrations-postgresql:
runs-on: ubuntu-latest

services:
postgres:
image: postgres:16
env:
POSTGRES_DB: auth_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5

env:
PGHOST: 127.0.0.1
PGPORT: 5432
PGDATABASE: auth_test
PGUSER: postgres
PGPASSWORD: postgres

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.5"
extensions: pdo_pgsql
coverage: none

- name: Install dependencies
run: composer install --no-interaction --prefer-dist

- name: Run bundled Phinx migrations
run: vendor/bin/phinx migrate --configuration test/phinx.php --environment testing

- name: Verify migration status
run: vendor/bin/phinx status --configuration test/phinx.php --environment testing

- name: Verify migrated schema
run: php test/verify_migrations.php

- name: Verify portable role lookup
run: php test/verify_postgresql_role_lookup.php
109 changes: 109 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
name: Release verification

on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:

jobs:
test:
# The regular CI workflow already tests the full PHP matrix on PRs.
# This release workflow runs the matrix after merge or when dispatched.
if: github.event_name != 'pull_request'
name: PHP ${{ matrix.php }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php:
- '8.2'
- '8.3'
- '8.4'
- '8.5'

steps:
- name: Checkout
uses: actions/checkout@v7

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: none
tools: composer:v2

- name: Validate Composer metadata
run: composer validate --strict

- name: Install dependencies
run: composer update --prefer-dist --no-interaction --no-progress

- name: Run tests
run: vendor/bin/phpunit test

production-install:
name: Production install
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v7

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
coverage: none
tools: composer:v2

- name: Validate Composer metadata
run: composer validate --strict

- name: Verify production dependencies
run: |
composer install --no-dev --prefer-dist --no-interaction --no-progress --optimize-autoloader
composer check-platform-reqs --no-dev

- name: Smoke-test production autoload and authentication
run: php test/verify_production_install.php vendor/autoload.php

- name: Install as a separate production consumer
shell: bash
run: |
set -euo pipefail
mkdir -p "$RUNNER_TEMP/auth-consumer"
# This prerelease is not yet published on Packagist. Use a copied
# Composer path package (not a symlink) pinned to the candidate
# version, as a real consumer would install it into vendor/.
php -r '
$manifest = [
"name" => "objectiveweb/auth-production-consumer",
"description" => "Isolated no-dev install verification",
"require" => [
"php" => ">=8.2",
"objectiveweb/auth" => "^0.2",
],
"repositories" => [[
"type" => "path",
"url" => getenv("GITHUB_WORKSPACE"),
"options" => [
"symlink" => false,
"versions" => ["objectiveweb/auth" => "0.2.0"],
],
]],
];
file_put_contents(
getenv("RUNNER_TEMP") . "/auth-consumer/composer.json",
json_encode($manifest, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n"
);
'
cd "$RUNNER_TEMP/auth-consumer"
composer install --no-dev --prefer-dist --no-interaction --no-progress --optimize-autoloader
composer check-platform-reqs --no-dev
test -f vendor/objectiveweb/auth/src/Auth.php
php "$GITHUB_WORKSPACE/test/verify_production_install.php" "$PWD/vendor/autoload.php"

19 changes: 0 additions & 19 deletions .travis.yml

This file was deleted.

65 changes: 65 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Changelog

All notable changes to `objectiveweb/auth` are documented here. This project follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) conventions and [Semantic Versioning](https://semver.org/); releases prior to 1.0 may include breaking changes in minor versions.

## [0.2.0] — Unreleased

**Breaking release.** This is a rewrite of the 0.1.x public API and storage model, not a drop-in upgrade. Read the [0.2.0 upgrade guide](docs/UPGRADING-0.2.0.md) before updating an existing application.

### Added

- Abstract `Objectiveweb\Auth` provider contract, `Objectiveweb\Auth\DBAuth` backed by `objectiveweb/db ^0.8`, and an in-memory `BasicAuth` provider.
- Separate user and `(provider, uid)` credential records, provider-specific profiles, UUIDs, configurable login/recovery providers, credential lifecycle (create, rename, delete) and per-credential verification status.
- Bundled Phinx migrations for `user`, `user_credentials`, `role`, `user_roles`, and `delegations`, including credential verification/expiry columns.
- Role-based authorization, `RequireRole` middleware, relational permissions/delegations, configurable eager loading, and `user_context_callback` for refreshing application-owned context in sessions.
- `Controller\AuthController`, `Controller\OAuthController`, and admin-only `Controller\UserController` with paginated, filterable `Collection` results, credential management, invitations, password resets, lifecycle management and CSRF-protected writes.
- Optional OAuth client login with Google/Facebook provider support, PKCE S256, provider/session-bound single-use state, and explicit, CSRF-protected account linking.
- A **first-time OAuth account-choice flow**: an unknown provider identity remains pending for up to ten minutes. The user explicitly chooses to create a new account or sign into an existing password account to link; the provider callback creates no account by itself. Includes an example frontend.
- Configurable callbacks for registration, token delivery, invitation/reset, audit events, deletion guards and application context.
- PHP 8.2–8.5 tests, SQLite unit tests, PostgreSQL 16 migration/integration checks, MySQL 8.0/8.4 schema and authentication integration checks, real Google/Facebook provider-class tests with mocked HTTP, and pre-merge production/consumer Composer installation tests.

### Changed

- **Minimum PHP version raised from 5.3 to 8.2.** Runtime dependency: `objectiveweb/db ^0.8.0`. Router/Phinx/PHPUnit packages are development dependencies; applications using router middleware or OAuth providers must install the relevant integration packages themselves.
- Database access moved from direct PDO/MySQL-specific SQL in `Objectiveweb\Auth` to the portable `DBAuth` abstraction. Queries now return `Objectiveweb\DB\Collection`, rather than the 0.1.x HAL-style `_embedded`/pagination array.
- Local identifiers are represented as credentials (`provider = local`, `uid`); the user table no longer contains the legacy `username` identity column by default.
- Password login failures return the same `AuthException` HTTP 401 for unknown identifiers, bad passwords and suspended accounts.
- Password reset tokens are cryptographically random, stored only as SHA-256 digests, expire and are consumed atomically; previously issued plaintext legacy tokens do **not** carry forward.
- Session IDs regenerate upon authentication; `user_can()` revalidates account status and roles on every call so deleted/suspended accounts and revoked roles cannot retain access through stale sessions. Public user payloads are sanitized.
- User-facing password changes require the existing password, a session-bound `X-CSRF-Token`, and a JSON request; public registration is restricted to local credentials and safe profile fields.
- OAuth callbacks require a **configured, trusted `redirectUri`** (HTTPS, or explicitly configured HTTP loopback for local development), no longer inferred from Host/proxy request headers.
- OAuth provider-resource-owner display names, emails and avatars are optional hints with safe fallbacks; matching email addresses do **not** link accounts.
- `BasicAuth::update_credential()` now preserves an existing provider profile when given `null`, matching `DBAuth` and preventing password login from erasing metadata.
- User-managed application associations (`managed_relations`) now belong to application services. Use `user_context_callback` to expose current assignments to the authenticated session. User deletion cleans only explicitly `auth_owned` authorization relation tables; application-owned relation tables are never implicitly modified.
- Project testing/release verification moved from Travis to GitHub Actions; Composer metadata and support URL updated.

### Security fixes

- Prevent account enumeration through password-login errors and anonymous password-recovery responses.
- Allow anonymous password recovery only through independently verified credential channels (including local), preventing reset delivery to unverified emails/phone numbers; preserve generic responses and trusted administrator invitation/reset workflows.
- Consume password reset and credential-verification tokens at most once; separate proof for each provider credential.
- Revoke outstanding password-reset tokens and expirations whenever a user password is changed, atomically with the password hash update on DBAuth.
- Prevent OAuth login CSRF, state replay, cross-provider state confusion, unconsented linking, email-based account takeover and cross-account credential reassignment.
- Restrict logout redirects to safe same-origin absolute paths and reject attacker-controlled OAuth callback URLs.
- Enforce management CSRF checks; check and serialize administrator removal, demotion and suspension inside DBAuth's existing update/delete transactions so concurrent operations cannot remove the final active admin (including direct DBAuth calls and lifecycle-field updates). Routine profile writes skip the lock; controllers retain self-protection and validation. Reject unknown DELETE subresources with 404 instead of accidentally deleting the user.
- Avoid returning passwords, reset tokens or other internal secrets in normal user/session/management payloads.

### Removed / incompatible

- Direct construction of `new Objectiveweb\Auth($pdo, ...)`; instantiate `DBAuth` or `BasicAuth` instead.
- `Objectiveweb\Auth\AuthController` (old class path), `PasswordMismatchException`, legacy `src/password.php`, and the 0.1.x MySQL-only query format.
- Implicit ownership of application-managed relations and implicit OAuth account linking based on email.
- Legacy plaintext password-reset token storage/consumption.

### Deferred / not included

- Built-in rate limiting is intentionally excluded. Deployments **must** configure throttling at the reverse proxy, gateway, WAF or application middleware. Planned non-SQL pluggable throttling: [#2](https://github.com/objectiveweb/auth/issues/2).
- Acting as an OAuth2/OIDC identity provider, JWT signing/JWKS: [#3](https://github.com/objectiveweb/auth/issues/3).
- WebAuthn/passkeys, TOTP and MFA: [#4](https://github.com/objectiveweb/auth/issues/4).
- Refresh-token rotation, device/session management and advanced audit sinks: [#5](https://github.com/objectiveweb/auth/issues/5).

See [release notes](docs/RELEASE-0.2.0.md) for a concise announcement and the [upgrade guide](docs/UPGRADING-0.2.0.md) for required migration steps. This entry is **unreleased** until the PR is merged and a release tag is published.

## 0.1.x — Legacy series

The previous public API used a concrete, PDO-backed `Objectiveweb\Auth`, a single `ow_auth` user table with a `username` column, `Objectiveweb\Auth\AuthController` and PHP 5.3-era dependencies. This entry describes the legacy series for comparison; its individual release dates and tag history are not reconstructed here.
Loading
Loading