# ONES OIDC Authentication Library

## Installation

```bash
composer require ones/oidc
```

## Usage

### Setup

```php
<?php

require_once __DIR__ . '/../vendor/autoload.php';

use ones\oidc\OnesOidc;

$loginHint = "some.user@onesid1.org";
$resourceUri = "https://my-service.com";

try {
    // Create an instance of OnesOidc
    $oidc = new OnesOidc();

    // Get device properties
    $deviceProps = $oidc->get_device_properties(
        '/etc/px-device-identity/device.yml',         // Update path as needed
        '/root/.local/share/px-device-identity/private.pem'     // Update path as needed
    );

    // Get OpenID configuration
    $openidInfo = $oidc->get_openid_info($deviceProps['host']);

    // CONTINUE WITH 
    // - CIBA AUTHENTICATION
    // - OR AUTHENTICATION

} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
    exit(1);
}

?>
```

### CIBA Authentication

```php
<?php

// CONTINUE FROM SETUP

$result = $oidc->user_ciba_auth(
    $loginHint,
    $deviceProps['clientId'],
    $deviceProps['privateKey'],
    $openidInfo['providerMetadata'],
    $openidInfo['providerJwks'],
    $resourceUri,
    "Please authorize this request",
    "openid profile"
);

// Print result
echo "CIBA Authentication Result:\n";
echo json_encode($result, JSON_PRETTY_PRINT) . "\n";

// Test consent flow
$consentSettings = [
    'ones_auth_consent_content_first_name' => true,
    'ones_auth_consent_content_last_name' => true,
    'ones_auth_consent_content_email' => true,
    'ones_auth_consent_content_phone_number' => true
];

$consentReason = 'Requesting access';

$consentResult = $oidc->user_consent_flow(
    $result['access_token_content']['sub'],
    $deviceProps['clientId'],
    $deviceProps['privateKey'],
    $openidInfo['providerMetadata'],
    $resourceUri,
    $deviceProps['host'],
    $consentSettings,
    $consentReason
);

// Print consent flow result
echo "\nConsent Flow Result:\n";
echo json_encode($consentResult, JSON_PRETTY_PRINT) . "\n";

?>
```

All options for consent fields are:

```php
[
    'ones_auth_consent_content_first_name' => true,
    'ones_auth_consent_content_last_name' => true,
    'ones_auth_consent_content_localized_first_name' => true,
    'ones_auth_consent_content_localized_last_name' => true,
    'ones_auth_consent_content_identity_document_number' => true,
    'ones_auth_consent_content_identity_document_issue_date' => true,
    'ones_auth_consent_content_identity_document_expiry_date' => true,
    'ones_auth_consent_content_date_of_birth' => true,
    'ones_auth_consent_content_email' => true,
    'ones_auth_consent_content_phone_number' => true
]
```

### QR Authentication

```php
<?php

// CONTINUE FROM SETUP

$qrSession = $oidc->make_qr_auth_session(
    $deviceProps['host'],
    $deviceProps['clientId'],
    $deviceProps['privateKey'],
    $openidInfo['providerMetadata'],
);

// Generate QR code
echo "\nPlease scan the QR code using your mobile device.\n";
echo "Session ID:   " . $qrSession['sessionId'] . "\n";
echo "Callback URL: " . $qrSession['cbUrl'] . " \n\n";

$authRequestId = null;

// Poll QR auth session until completion or timeout
echo "Polling QR Auth Session...\n";
while (true) {
    $result = $oidc->poll_qr_auth_session(
        $qrSession['sessionId'],
        $deviceProps['clientId'],
        $deviceProps['privateKey'],
        $openidInfo['providerMetadata'],
        // $openidInfo['providerJwks'],
        $resourceUri,
        $deviceProps['host'],
        "Please authorize this request",
        "openid profile"
    );

    if ($result && isset($result['authRequestId'])) {
        $authRequestId = $result['authRequestId'];
        break;
    }

    sleep(3);
}

// Poll CIBA status
echo "Polling CIBA Status with Auth Request ID: $authRequestId...\n";
while (true) {
    $result = $oidc->check_ciba_status_loop(
        $openidInfo['providerMetadata'],
        $openidInfo['providerJwks'],
        $authRequestId,
        $deviceProps['clientId'],
        $deviceProps['privateKey']
    );

    // when access_token is set, break the loop
    if ($result && isset($result['access_token'])) {
        echo "CIBA Authentication Result:\n";
        break;
    }

    sleep(3);
}

?>
```

## Testing

Setup environment:

```bash
guix shell php
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
php composer.phar install
```

Run CIBA test:

```bash
export OIDC_LOGIN_HINT="some.user@onesid1.org" && export OIDC_RESOURCE_URI="https://my-service.com" && php tests/test.php
```

Run QR test:

```bash
# Without consent
OIDC_RESOURCE_URI="https://my-service.com" php tests/test_qr.php

# With consent
OIDC_RESOURCE_URI=<"https://my-service.com"> INCLUDE_CONSENT=1 php tests/test_qr.php
```