Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
093b751
Pin released dependencies: MySQL 4, PostgreSQL 5, Redis 4, SQLite 6, …
taplin Oct 14, 2026
8787954
Tests: live suites skip visibly, fail when unreachable or required
taplin Oct 14, 2026
4ba8656
Don't crash saving session data JSON can't hold
taplin Oct 14, 2026
df32683
CORS: a wildcard origin must match both sides of the *
taplin Oct 14, 2026
763cd22
Redis sessions: namespaced keys, no resurrection, TTL from the session
taplin Oct 14, 2026
9a5a892
Memory sessions: save() no longer recreates a destroyed session
taplin Oct 14, 2026
c7b53ae
Don't trap on a huge session idle time
taplin Oct 14, 2026
7b1394f
MySQL/PostgreSQL sessions: 64-bit times, overflow-safe clean()
taplin Oct 14, 2026
4e258f2
PostgreSQL: percent-encode connection URI parts fully
taplin Oct 14, 2026
61d59f4
Every driver's resume() refuses an expired session; optional absolute…
taplin Oct 14, 2026
ac62cf7
Generate session and CSRF tokens with SystemRandomNumberGenerator
taplin Oct 14, 2026
0428231
Add SessionDriver.regenerate() against session fixation
taplin Oct 14, 2026
89b5120
Add SessionCookie: Set-Cookie values from SessionConfig's cookie sett…
taplin Oct 14, 2026
fc8424e
Tests: injection probes for the SQL and MongoDB backends
taplin Oct 14, 2026
5d54233
Concurrency tests; checks take explicit config so tests don't race
taplin Oct 14, 2026
86ec917
Drop @unchecked from the stateless SQL drivers' Sendable
taplin Oct 14, 2026
0245653
MySQL: don't trap on an out-of-range port
taplin Oct 14, 2026
7202fb9
CI: Swift 6.2/6.4 x debug/release, warnings as errors, live tests req…
taplin Oct 14, 2026
d5364ed
README: 4.0.0 install, security notes, Perfect-NIO example, migration
taplin Oct 14, 2026
44f2fdd
AuthFilter: segment matching, case-folding, fail closed; requiresAuth…
taplin Oct 14, 2026
7640239
A value JSON can't hold drops only its own key, never the CSRF token
taplin Oct 14, 2026
1847a2c
Every driver's save() renews the idle time
taplin Oct 14, 2026
3c29930
regenerate() keeps the session's creation time
taplin Oct 14, 2026
dc3112d
Log a SHA-256 prefix of the session token, never the token
taplin Oct 14, 2026
271ceeb
Deprecate the config knobs nothing reads; add CSRFSecurity.tokenMatches
taplin Oct 14, 2026
4f3f42d
Redis: clamp the TTL so a huge idle doesn't make save() fail
taplin Oct 14, 2026
a19e616
Redis: commandTimeout defaults to 5 seconds
taplin Oct 14, 2026
10a030f
SessionCookie: recognize __Host-/__Secure- prefixes in any case
taplin Oct 14, 2026
ede3dab
CSRFSecurity.isValid: compare scheme, default ports and case
taplin Oct 14, 2026
d0c267e
clean(), the MongoDB TTL index and Redis TTLs honour absoluteTimeout
taplin Oct 14, 2026
8073d21
README and docs: review fixes, CSRF and auth middleware example
taplin Oct 14, 2026
5371df5
README.zh_CN: CSRF, AuthFilter, save renewal, Redis 5 s timeout
taplin Oct 14, 2026
8c6e5a0
Tests: skip exit tests under ThreadSanitizer; save() renews updated
taplin Oct 14, 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
97 changes: 85 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,25 @@ on:
push:
pull_request:

permissions:
contents: read

env:
MONGOC_VERSION: 2.5.5

jobs:
linux:
# Every backend against a real server (SQLite uses a local file).
name: Linux (Swift 6.4, all backends)
name: Linux (Swift ${{ matrix.swift }}, ${{ matrix.configuration }})
runs-on: ubuntu-24.04
container: swift:6.4-resolute
container: swift:${{ matrix.swift }}-noble
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
# The oldest supported Swift (swift-tools-version 6.2) and the newest.
swift: ["6.2", "6.4"]
configuration: [debug, release]
services:
mongo:
image: mongo:8
Expand All @@ -34,40 +47,100 @@ jobs:
MONGODB_URI: mongodb://mongo:27017
PG_TESTS: "1"
PG_HOST: postgres
PG_PORT: "5432"
MYSQL_TESTS: "1"
MYSQL_HOST: mysql
MYSQL_PORT: "3306"
REDIS_TESTS: "1"
REDIS_HOST: redis
REDIS_PORT: "6379"
SQLITE_TESTS: "1"
# Fail, rather than skip, if a backend's tests aren't switched on or can't reach its server.
SESSION_REQUIRE_LIVE: "1"
# Expiry is epoch seconds; it must not depend on the process's time zone.
TZ: America/Denver
steps:
- uses: actions/checkout@v7

- name: Install client libraries
run: |
apt-get update
apt-get install -y --no-install-recommends pkg-config libmongoc-dev libbson-dev libpq-dev libmysqlclient-dev libsqlite3-dev
apt-get install -y --no-install-recommends pkg-config libpq-dev libmysqlclient-dev libsqlite3-dev \
build-essential cmake curl libssl-dev libsasl2-dev libzstd-dev

# Ubuntu 24.04's libmongoc is 1.x; Perfect-MongoDB 4 needs libmongoc 2.
- name: Cache libmongoc
id: mongoc-cache
uses: actions/cache@v6
with:
path: /opt/mongoc
key: mongoc-${{ env.MONGOC_VERSION }}-noble

- name: Build libmongoc
if: steps.mongoc-cache.outputs.cache-hit != 'true'
run: |
curl -fsSL https://github.com/mongodb/mongo-c-driver/releases/download/$MONGOC_VERSION/mongo-c-driver-$MONGOC_VERSION.tar.gz | tar xz
cmake -S mongo-c-driver-$MONGOC_VERSION -B mongoc-build \
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/mongoc \
-DENABLE_TESTS=OFF -DENABLE_EXAMPLES=OFF
cmake --build mongoc-build --parallel
cmake --install mongoc-build

- name: Use libmongoc
run: |
echo "PKG_CONFIG_PATH=$(dirname "$(find /opt/mongoc -name mongoc2.pc)")" >> "$GITHUB_ENV"
echo "LD_LIBRARY_PATH=$(dirname "$(find /opt/mongoc -name 'libmongoc2.so' | head -1)")" >> "$GITHUB_ENV"

- name: Toolchain
run: swift --version

- name: Build (warnings are errors)
run: |
flags="-c ${{ matrix.configuration }} -Xswiftc -warnings-as-errors"
# @testable imports need testing enabled in an optimized build.
[ "${{ matrix.configuration }}" = release ] && flags="$flags -Xswiftc -enable-testing"
echo "FLAGS=$flags" >> "$GITHUB_ENV"
swift build --build-tests $flags

- name: Test
run: swift test
run: swift test $FLAGS

macos:
# GitHub's macOS runners have no database servers, so this covers the build plus the
# server-independent tests, including SQLite (a local file).
name: macOS (build, core and SQLite tests)
# GitHub's macOS runners have no database servers, so this covers the build, the
# server-independent tests and SQLite (a local file); the other live suites report as skipped.
name: macOS (Xcode ${{ matrix.xcode }}, ${{ matrix.configuration }})
runs-on: macos-26
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
# The oldest Xcode with Swift 6.2, and the runner's default.
xcode: ["26.0.1", "26.6"]
configuration: [debug, release]
env:
SQLITE_TESTS: "1"
TZ: America/Denver
steps:
- uses: actions/checkout@v7

- name: Select Xcode
run: |
sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode }}.app
swift --version

- name: Install client libraries
run: |
brew install mongo-c-driver mysql-client libpq
# Keg-only; older SwiftPM releases don't find libpq through its brew provider alone.
brew install mongo-c-driver mysql-client libpq pkgconf
# mysql-client and libpq are keg-only, so pkg-config can't find their .pc files without this.
echo "PKG_CONFIG_PATH=$(brew --prefix libpq)/lib/pkgconfig:$(brew --prefix mysql-client)/lib/pkgconfig" >> "$GITHUB_ENV"

- name: Toolchain
run: swift --version
- name: Build (warnings are errors)
run: |
flags="-c ${{ matrix.configuration }} -Xswiftc -warnings-as-errors"
# @testable imports need testing enabled in an optimized build.
[ "${{ matrix.configuration }}" = release ] && flags="$flags -Xswiftc -enable-testing"
echo "FLAGS=$flags" >> "$GITHUB_ENV"
swift build --build-tests $flags

- name: Test
run: swift test
run: swift test $FLAGS
13 changes: 8 additions & 5 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,19 @@ let package = Package(
.library(name: "PerfectSessionMongoDB", targets: ["PerfectSessionMongoDB"]),
],
dependencies: [
.package(url: "https://github.com/PerfectlySoft/Perfect-MySQL.git", branch: "main"),
.package(url: "https://github.com/PerfectlySoft/Perfect-PostgreSQL.git", branch: "main"),
.package(url: "https://github.com/PerfectlySoft/Perfect-Redis.git", branch: "main"),
.package(url: "https://github.com/PerfectlySoft/Perfect-SQLite.git", branch: "main"),
.package(url: "https://github.com/PerfectlySoft/Perfect-MongoDB.git", from: "4.0.2"),
.package(url: "https://github.com/PerfectlySoft/Perfect-MySQL.git", from: "4.0.0"),
.package(url: "https://github.com/PerfectlySoft/Perfect-PostgreSQL.git", from: "5.0.0"),
.package(url: "https://github.com/PerfectlySoft/Perfect-Redis.git", from: "4.0.0"),
.package(url: "https://github.com/PerfectlySoft/Perfect-SQLite.git", from: "6.0.0"),
.package(url: "https://github.com/PerfectlySoft/Perfect-MongoDB.git", from: "4.0.3"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.0"),
],
targets: [
.target(
name: "PerfectSessionCore",
dependencies: [
.product(name: "Logging", package: "swift-log"),
],
swiftSettings: [.swiftLanguageMode(.v6)]
),
.target(
Expand Down
Loading
Loading