Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ vendor/*
.idea
.env
.authenticator
.state
.state
/my-scratch-project/
14 changes: 12 additions & 2 deletions .tinkerwell/SalesforcePhpTinkerwellDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,18 @@ public function getAvailableVariables()
return [
'api' =>(function() : SalesforceApi {
$api = new SalesforceApi($_ENV['SALESFORCE_INSTANCE_URL']);
$api->restoreExistingOAuthConnection((file_get_contents('.authenticator')), function($authenticator) {
file_put_contents('.authenticator', $authenticator->serialize());
$stored = json_decode(file_get_contents('.authenticator'), true);
$authenticator = new \Saloon\Http\Auth\AccessTokenAuthenticator(
accessToken: $stored['access_token'],
refreshToken: $stored['refresh_token'] ?? '',
expiresAt: isset($stored['expires_at']) ? new \DateTimeImmutable($stored['expires_at']) : null,
Comment thread
tance77 marked this conversation as resolved.
);
$api->restoreExistingOAuthConnection($authenticator, function($authenticator) {
file_put_contents('.authenticator', json_encode([
'access_token' => $authenticator->getAccessToken(),
'refresh_token' => $authenticator->getRefreshToken(),
'expires_at' => $authenticator->getExpiresAt()?->format(DATE_ATOM),
]));
});
return $api;
})()
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
}
],
"require": {
"php": ">=8.0",
"php": ">=8.2",
"league/csv": "^9.8",
"saloonphp/saloon": "^2.0"
"saloonphp/saloon": "^4.0"
},
"require-dev": {
"pestphp/pest": "4",
Expand Down
42 changes: 22 additions & 20 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion index.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@
echo "<p>Access Token: <code>$token</code></p>";
echo "<p>Refresh Token: <code>$refresh</code></p>";

file_put_contents('.authenticator', $authenticator->serialize());
file_put_contents('.authenticator', json_encode([
'access_token' => $authenticator->getAccessToken(),
'refresh_token' => $authenticator->getRefreshToken(),
'expires_at' => $authenticator->getExpiresAt()?->format(DATE_ATOM),
]));
Comment thread
tance77 marked this conversation as resolved.
echo json_encode($salesforceApi->getCurrentUserInfo(), JSON_PRETTY_PRINT);

echo '<p>Token is ready, you can use the authenticator by deserializing .authenticator in the root or boot tinkerwell and just use $api.</p>';
Expand Down
3 changes: 2 additions & 1 deletion src/Connectors/SalesforceOAuthLoginConnector.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use myoutdeskllc\SalesforcePhp\Requests\OAuth\GetAccessTokenWithPKCERequest;
use myoutdeskllc\SalesforcePhp\SalesforceApi;
use Saloon\Contracts\OAuthAuthenticator;
use Saloon\Contracts\Response;
use Saloon\Http\Response;
use Saloon\Exceptions\InvalidStateException;
use Saloon\Http\Connector;
use Saloon\Http\OAuth2\GetAccessTokenRequest;
Expand All @@ -24,6 +24,7 @@ public function setOauthConfiguration(OAuthConfiguration $configuration, string
$this->oauthConfig()->setRedirectUri($configuration->getRedirectUri());
$this->oauthConfig()->setAuthorizeEndpoint($this->resolveBaseUrl().'/services/oauth2/authorize');
$this->oauthConfig()->setTokenEndpoint($this->resolveBaseUrl().'/services/oauth2/token');
$this->oauthConfig()->setAllowBaseUrlOverride();
$this->codeVerifier = $codeVerifier;
}

Expand Down
2 changes: 2 additions & 0 deletions src/Requests/Auth/LoginApiUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
class LoginApiUser extends Request implements HasBody
{
use HasFormBody;

public ?bool $allowBaseUrlOverride = true;
protected Method $method = Method::POST;

public function defaultBody(): array
Expand Down
2 changes: 1 addition & 1 deletion src/Requests/BulkApi/UploadJobData.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class UploadJobData extends Request implements HasBody
{
use \Saloon\Traits\Body\HasBody;
use \Saloon\Traits\Body\HasStringBody;

protected string $jobId;
protected AbstractCsv $stream;
Expand Down
2 changes: 2 additions & 0 deletions src/Requests/OAuth/GetAccessTokenWithPKCERequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class GetAccessTokenWithPKCERequest extends Request implements HasBody
use HasFormBody;
use AcceptsJson;

public ?bool $allowBaseUrlOverride = true;

/**
* Define the method that the request will use.
*
Expand Down
1 change: 1 addition & 0 deletions src/Requests/OAuth2/UserInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

class UserInfo extends Request
{
public ?bool $allowBaseUrlOverride = true;
protected Method $method = Method::GET;

public function resolveEndpoint(): string
Expand Down
14 changes: 6 additions & 8 deletions src/SalesforceApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,10 @@ public function completeOAuthLogin(OAuthConfiguration $configuration, string $co
return $authenticator;
}

public function restoreExistingOAuthConnectionWithCodeVerification($serializedAuthenticator, OAuthConfiguration $originalConfiguration, string $codeVerifier, callable $afterRefresh)
public function restoreExistingOAuthConnectionWithCodeVerification(AccessTokenAuthenticator $authenticator, OAuthConfiguration $originalConfiguration, string $codeVerifier, callable $afterRefresh)
{
$connector = new Connectors\SalesforceOAuthLoginConnector();
$connector->setOauthConfiguration($originalConfiguration, $codeVerifier);
$authenticator = AccessTokenAuthenticator::unserialize($serializedAuthenticator);
$connector->authenticate($authenticator);

if ($authenticator->hasExpired() || $authenticator->getExpiresAt() === null) {
Expand All @@ -132,10 +131,9 @@ public function restoreExistingOAuthConnectionWithCodeVerification($serializedAu
$this->connector->authenticate($authenticator);
}

public function restoreExistingOAuthConnection($serializedAuthenticator, callable $afterRefresh)
public function restoreExistingOAuthConnection(AccessTokenAuthenticator $authenticator, callable $afterRefresh)
{
$connector = new Connectors\SalesforceOAuthLoginConnector();
$authenticator = AccessTokenAuthenticator::unserialize($serializedAuthenticator);
$connector->authenticate($authenticator);

if ($authenticator->hasExpired()) {
Expand All @@ -147,9 +145,9 @@ public function restoreExistingOAuthConnection($serializedAuthenticator, callabl
$this->connector->authenticate($authenticator);
}

public function refreshToken($serializedAuthenticator, callable $afterRefresh)
public function refreshToken(AccessTokenAuthenticator $authenticator, callable $afterRefresh)
{
$this->restoreExistingOAuthConnection($serializedAuthenticator, $afterRefresh);
$this->restoreExistingOAuthConnection($authenticator, $afterRefresh);
}

public static function getApiVersion(): string
Expand Down Expand Up @@ -259,7 +257,7 @@ public function recordsOnly(): self
protected function executeRequestSync(Request $request): Response
{
if ($this->eatErrors) {
return $this->connector->send($request); // @phpstan-ignore-line
return $this->connector->send($request);
}

$response = $this->connector->send($request);
Expand All @@ -268,7 +266,7 @@ protected function executeRequestSync(Request $request): Response
$response->throw();
}

return $response; // @phpstan-ignore-line
return $response;
}

/**
Expand Down
14 changes: 12 additions & 2 deletions tests/Pest.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,18 @@ function getAPI()
$api = new SalesforceApi($_ENV['SALESFORCE_INSTANCE_URL'], $_ENV['API_VERSION']);

// this is questionable, but works for testing with OAuth connections
$api->restoreExistingOAuthConnection(file_get_contents('.authenticator'), function ($authenticator) {
file_put_contents('.authenticator', $authenticator->serialize());
$stored = json_decode(file_get_contents('.authenticator'), true);
$authenticator = new \Saloon\Http\Auth\AccessTokenAuthenticator(
accessToken: $stored['access_token'],
refreshToken: $stored['refresh_token'] ?? '',
expiresAt: isset($stored['expires_at']) ? new \DateTimeImmutable($stored['expires_at']) : null,
Comment thread
tance77 marked this conversation as resolved.
);
$api->restoreExistingOAuthConnection($authenticator, function ($authenticator) {
file_put_contents('.authenticator', json_encode([
'access_token' => $authenticator->getAccessToken(),
'refresh_token' => $authenticator->getRefreshToken(),
'expires_at' => $authenticator->getExpiresAt()?->format(DATE_ATOM),
]));
});

$api->recordsOnly();
Expand Down
Loading