├── .gitignore
├── CONTRIBUTING.md
├── phpunit.xml
├── src
└── IndieAuth
│ ├── ErrorResponse.php
│ └── Client.php
├── composer.json
├── tests
├── bootstrap.php
├── NormalizeTest.php
├── ScopeTest.php
├── DiscoveryTest.php
├── ClientTest.php
└── MetadataTest.php
├── .github
└── workflows
│ └── main.yml
├── LICENSE.txt
├── README.md
└── composer.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor/
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | By contributing to this project, you agree to irrevocably release your contributions under the same licenses as this project. See README.md for more details.
2 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | tests/
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/IndieAuth/ErrorResponse.php:
--------------------------------------------------------------------------------
1 | code = $code;
14 | $this->description = $description;
15 | $this->debug = $debug;
16 | }
17 |
18 | /**
19 | * @return array
20 | */
21 | public function getArray()
22 | {
23 | $response = [
24 | 'error' => $this->code,
25 | 'error_description' => $this->description,
26 | ];
27 |
28 | if ($this->debug) {
29 | $response['debug'] = $this->debug;
30 | }
31 |
32 | return [false, $response];
33 | }
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "indieauth/client",
3 | "description": "IndieAuth Client Library",
4 | "require": {
5 | "php": ">5.6.0",
6 | "mf2/mf2": "^0.5",
7 | "p3k/http": "^0.1",
8 | "indieweb/representative-h-card": "^0.1.2"
9 | },
10 | "license": "Apache-2.0",
11 | "authors": [
12 | {
13 | "name": "Aaron Parecki",
14 | "homepage": "https://aaronparecki.com"
15 | }
16 | ],
17 | "funding": [
18 | {
19 | "type": "opencollective",
20 | "url": "https://opencollective.com/indieweb"
21 | }
22 | ],
23 | "autoload": {
24 | "psr-4": {
25 | "IndieAuth\\": "src/IndieAuth/"
26 | }
27 | },
28 | "require-dev": {
29 | "yoast/phpunit-polyfills": "^1.0"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 | getMethod($methodName);
12 | $method->setAccessible(true);
13 | return $method->invokeArgs($object, $params);
14 | }
15 |
16 | protected function _invokeStaticMethod($class, $methodName, $params=[]) {
17 | $reflection = new \ReflectionClass($class);
18 | $method = $reflection->getMethod($methodName);
19 | $method->setAccessible(true);
20 | return $method->invokeArgs(null, $params);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Unit Tests
2 |
3 | on:
4 | push:
5 | branches: [ "main" ]
6 | pull_request:
7 | branches: [ "main" ]
8 | workflow_dispatch:
9 |
10 | permissions:
11 | contents: read
12 |
13 | jobs:
14 | build:
15 |
16 | strategy:
17 | matrix:
18 | php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1']
19 |
20 | runs-on: ubuntu-latest
21 |
22 | steps:
23 | - uses: actions/checkout@v3
24 |
25 | - name: Validate composer.json and composer.lock
26 | run: composer validate --strict
27 |
28 | - name: Cache Composer packages
29 | id: composer-cache
30 | uses: actions/cache@v3
31 | with:
32 | path: vendor
33 | key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
34 | restore-keys: |
35 | ${{ runner.os }}-php-
36 |
37 | - name: Install dependencies
38 | run: composer install --prefer-dist --no-progress
39 |
40 | - name: Run test suite
41 | run: ./vendor/bin/phpunit
42 |
43 |
--------------------------------------------------------------------------------
/tests/NormalizeTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('http://aaronpk.com/', $normalized);
9 | }
10 |
11 | public function testNoSchemeWithPath() {
12 | $url = 'aaronpk.com/me';
13 | $normalized = IndieAuth\Client::normalizeMeURL($url);
14 | $this->assertEquals('http://aaronpk.com/me', $normalized);
15 | }
16 |
17 | public function testNoSlash() {
18 | $url = 'https://aaronpk.com';
19 | $normalized = IndieAuth\Client::normalizeMeURL($url);
20 | $this->assertEquals('https://aaronpk.com/', $normalized);
21 | }
22 |
23 | public function testRejectsInvalidScheme() {
24 | $url = 'mailto:me@example.com';
25 | $normalized = IndieAuth\Client::normalizeMeURL($url);
26 | $this->assertEquals(false, $normalized);
27 | }
28 |
29 | public function testAllowsQueryString() {
30 | $url = 'https://aaronpk.com?foo';
31 | $normalized = IndieAuth\Client::normalizeMeURL($url);
32 | $this->assertEquals('https://aaronpk.com/?foo', $normalized);
33 | }
34 |
35 | public function testRejectsFragment() {
36 | $url = 'https://aaronpk.com/#me';
37 | $normalized = IndieAuth\Client::normalizeMeURL($url);
38 | $this->assertEquals(false, $normalized);
39 | }
40 |
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/tests/ScopeTest.php:
--------------------------------------------------------------------------------
1 | assertTrue(is_array($scopes));
8 | $this->assertContains('create', $scopes);
9 | $this->assertContains('update', $scopes);
10 | $this->assertNotContains('profile', $scopes);
11 | $this->assertNotContains('email', $scopes);
12 | }
13 |
14 | public function testWorksWithEmptyScope() {
15 | $scopes = IndieAuth\Client::parseNonProfileScopes('');
16 | $this->assertTrue(is_array($scopes));
17 | $this->assertNotContains('profile', $scopes);
18 | $this->assertNotContains('email', $scopes);
19 | }
20 |
21 | public function testAcceptsFalseInput() {
22 | $scopes = IndieAuth\Client::parseNonProfileScopes(false);
23 | $this->assertTrue(is_array($scopes));
24 | $this->assertNotContains('profile', $scopes);
25 | $this->assertNotContains('email', $scopes);
26 | }
27 |
28 | public function testExcludesOneScope() {
29 | $scopes = IndieAuth\Client::parseNonProfileScopes('profile');
30 | $this->assertTrue(is_array($scopes));
31 | $this->assertNotContains('profile', $scopes);
32 | }
33 |
34 | public function testIncludesOneScope() {
35 | $scopes = IndieAuth\Client::parseNonProfileScopes('create');
36 | $this->assertTrue(is_array($scopes));
37 | $this->assertContains('create', $scopes);
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/tests/DiscoveryTest.php:
--------------------------------------------------------------------------------
1 |
Hello World