Skip to content

Public API

What this package exposes, as it is built today. Everything here is a promise to consumers: adding to it is a minor release, changing or removing it is a major one.

This page describes the code on main. A pull request that changes the surface changes this page in the same change.

Namespace layout

src/
├── LaravelAutentiqueServiceProvider.php   # merges the config, binds the contract
├── AutentiqueManager.php                  # the Autentique implementation
├── Contracts/                             # Autentique, GraphQLClient, FileSource
├── Api/                                   # one class per area of the API: Account, Corporate, Documents, Folders, OAuth, Organizations, PendingDocument, Signers
├── Commands/                              # CheckCommand, SchemaCommand
├── Events/                                # AutentiqueWebhookReceived
├── Facades/Autentique.php
├── Data/                                  # value objects returned: Document, Signature, User, …
│   └── Input/                             # value objects sent: NewDocument, Signer, Position, …
├── Enums/                                 # every closed set of API values, and ErrorCode
├── Io/                                    # PathFile, UploadedFileSource, DiskFile
├── Exceptions/                            # AutentiqueException and what extends it
├── GraphQL/                               # Client, ResponseParser, Operation, Endpoint, OperationLoader
└── Resources/graphql/                     # one .graphql file per operation

lang/{en,pt_BR}/errors.php                 # the text of every ErrorCode

The root namespace LSNepomuceno\LaravelAutentique is fixed; renaming it would be a gratuitous break.

The facade, and the contract behind it

Contracts\Autentique, resolved from the container as a singleton or reached through the Autentique facade, which is auto discovered.

MethodReturnsNotes
account()Api\Accountme() returns Data\User
documents()Api\Documentscreate(), find(), update(), block() return Data\Document; list() returns Data\Page<Document>; delete(), sign(), transfer(), moveToFolder() return bool
signers()Api\Signersadd(), approveBiometric(), rejectBiometric() return Data\Signature; link() returns Data\Link; remove(), resend() return bool
folders()Api\Foldersfind(), create(), rename(), share(), changeRole(), shareByLink(), stopSharingByLink(), removeLinkPassword() return Data\Folder; list() returns Data\Page<Folder>; documents() returns Data\Page<Document>; delete() returns bool
organizations()Api\Organizationscurrent() returns Data\Organization with groups; list() returns list<Organization>; emailTemplates() returns Data\Page<EmailTemplate>
corporate()Api\Corporatethe Corporate endpoint: child organizations, members, login codes, webhook endpoints, custom plans, API usage
oauth()Api\OAuthbegin() returns Data\Authorization; callback(), exchange(), refresh() return Data\OAuthTokens; OAuth::challenge() is the S256 challenge
withToken($token)Contracts\Autentiquethe whole API sending another token
newDocument($name)Api\PendingDocumentthe builder; send() returns Data\Document
fromPath($path, ?$name), fromUpload($file, ?$name), fromDisk($disk, $path, ?$name)Contracts\FileSourceLaravel only: uploads and disks stream
query($graphql, $variables)array<string, mixed>, the response's datathe escape hatch; values as variables, the document is the caller's

Every method must appear in the README, which tests/Project/ArchTest.php checks, and in the facade's @method docblock.

The transport

Contracts\GraphQLClient is bound to GraphQL\Client, the only class that reaches the network (invariant 1), the OAuth token endpoint included. It is a contract so the fake can stand in for it; an application may bind its own, at the cost of Http::fake() no longer reaching it.

Contracts\FileSource is what an upload reads: a name and contents, a string or a stream.

The contract is bound rather than the class, so an application can bind its own implementation in a service provider.

Operations

GraphQL\Operation names every operation the package sends, one case per file under src/Resources/graphql/. It is public because tests and the fake name operations by it. Adding a case is a minor release; removing or renaming one is a major release.

The selection of fields inside each file is not itself public: what is public is the value object built from it (0008).

Value objects

Every answer is a final readonly class under Data\, built from the fields its operation selects (0008). Property names are camel case ($hasPremiumFeatures for has_premium_features), dates are CarbonImmutable, and a field the API may omit is nullable.

ClassBuilt from
Data\Userme
Data\Subscription, Data\Organization, Data\Groupnested in the above, and in organization
Data\DocumentcreateDocument and every operation returning a document
Data\Page<T>every listing; countable, iterable, and filter() keeps Autentique's counts
Data\Folder, Data\FolderSummary, Data\FolderSharethe folder operations
Data\EmailTemplateemailTemplates
Data\ChildOrganization, Data\OrganizationMember, Data\OrganizationPlan, Data\CorporatePlan, Data\ApiUsage, Data\ApiUsageItems, Data\WebhookEndpointthe Corporate operations. OrganizationMember::$apiToken and WebhookEndpoint::$secret are credentials
Data\Authorization, Data\OAuthTokensthe OAuth flow; both carry credentials
Data\WebhookEventa webhook's body; the resource stays the array Autentique sent
Data\Signature, Data\Link, Data\Files, Data\Event, Data\Geolocation, Data\EmailEvents, Data\SignaturePosition, Data\Verificationnested in a document

An enum value the API returns and the package does not know yet becomes null rather than an exception, so a new value Autentique adds breaks nothing.

Inputs

What is sent is a final readonly class under Data\Input\: NewDocument, DocumentChanges, Share, Signer, PrefilledFields, NewChildOrganization, ChildOrganizationChanges, NewMember, NewSubscriptionPlan, Position, SecurityVerification, Locale, DocumentConfig, Expiration. Each refuses, with InvalidInput, a value Autentique documents it would refuse or silently change. toArray() returns what is sent, with every unset option left out so Autentique's default applies.

Api\PendingDocument is the one mutable class: a builder, whose methods return the same instance.

Adding a property is a minor release; removing one, or making a nullable one required, is a major release.

Support\Payload is how they read an answer. It is not public.

Exceptions

Everything the package throws extends Exceptions\AutentiqueException, which is abstract.

ExceptionWhen
RequestFailed (abstract)base of the nine below; carries $operation, $status, $requestId, $errors
UnauthenticatedHTTP 401, or the code unauthorized
InsufficientScopeUnauthorized, capitalised, with 200: an OAuth token without the scope
OAuthFailedan OAuth step failed; carries $error
RateLimitedHTTP 429 after the retries; carries $retryAfter
ValidationFailedmessage: "validation"; violations(), messages()
NotFounda *_not_found code, or a … not found message
ResendThrottledtoo_many_resent_emails on resendSignatures; wraps the GraphQLError
GraphQLErrorany other error, or no data
TransportFailedthe connection failed, or the answer was not GraphQL
MissingTokenno token configured, nothing sent
InvalidOperationan operation file is missing or spreads a fragment no file defines. A defect in the package, which the suite exists to prevent
UnexpectedResponsean answer without a field the package requires. The API and the package disagree about the schema
InvalidInputa value refused before sending
MissingWebhookSecreta webhook arrived with no secret to verify it
MissingOAuthCredentialsOAuth used without its configuration

Enums\ErrorCode lists every code Autentique documents; Data\ApiError and Data\Violation carry what arrived. Adding a case is a minor release.

Webhooks

Class
Webhooks\VerifyAutentiqueSignaturemiddleware; 401 on a bad signature, MissingWebhookSecret without a secret
Webhooks\SignatureVerifierverify($body, $signature, $secret), sign($body, $secret)
Webhooks\WebhookControllerthe route's controller; public so an application can reuse it on its own route
Events\AutentiqueWebhookReceiveddispatched with a Data\WebhookEvent
Enums\WebhookEventTypethe seventeen types

The route autentique.webhook, registered only when autentique.webhooks.path is set. Its answers are 200 {"received": true}, 200 {"received": true, "duplicate": true} for a dropped repeat, 400 for a signed body that is not an event, 401 for a bad signature.

Testing

Autentique::fake() returns Testing\AutentiqueFake, installed in place of Contracts\GraphQLClient. Its answers are shaped from what was sent; respond(), fail() and respondToQuery() override them. Its assertions are assertDocumentSent(), assertDocumentSentTimes(), assertNoDocumentSent(), assertSignerAdded(), assertResent(), assertSent(), assertNotSent(), assertSentTimes() and assertNothingSent(), and sent() returns every Testing\SentOperation.

Testing\FakeWebhook::make() builds a signed webhook body.

src/Testing uses PHPUnit's assertions, as Laravel's own fakes do, and runs only inside a test suite, where PHPUnit is installed.

Commands

CommandExit codes
autentique:check0 token accepted, 1 otherwise
autentique:schema {--output=}0 written, 1 refused

Their names and exit codes are public: a pipeline calls them.

Configuration

config/autentique.php, publishable with the autentique-config tag. Every key is a scalar (invariant 4).

KeyEnvironmentDefault
tokenAUTENTIQUE_TOKENnone
urlAUTENTIQUE_URLhttps://api.autentique.com.br/v2/graphql
corporate_urlAUTENTIQUE_CORPORATE_URLhttps://api.autentique.com.br/v2/graphql/corporate
sandboxAUTENTIQUE_SANDBOXfalse
timeoutAUTENTIQUE_TIMEOUT30 seconds
retry.timesAUTENTIQUE_RETRY_TIMES2
retry.sleepAUTENTIQUE_RETRY_SLEEP1000 milliseconds
webhooks.secretAUTENTIQUE_WEBHOOK_SECRETnone
webhooks.pathAUTENTIQUE_WEBHOOK_PATHnone, no route
webhooks.middleware[]
webhooks.deduplicateAUTENTIQUE_WEBHOOK_DEDUPLICATEnone, off
webhooks.cache_storeAUTENTIQUE_WEBHOOK_CACHE_STOREthe default store
oauth.client_id, oauth.client_secret, oauth.redirect_uriAUTENTIQUE_OAUTH_*none
oauth.urlAUTENTIQUE_OAUTH_URLhttps://api.autentique.com.br/oauth

Adding a key is a minor release. Removing or renaming one is a major release, because an application's published config file keeps the old name.

Experimental

Promised by nothing above until it has run against Autentique itself:

  • Api\Corporate, the operations under src/Resources/graphql/corporate/, and the value objects, inputs and enums only it uses;
  • Api\OAuth, Data\Authorization, Data\OAuthTokens, Enums\OAuthScope, and how Exceptions\InsufficientScope is recognised.

The Corporate endpoint needs an account on the Corporate plan, and OAuth a registered application; the maintainer's account had neither for 1.0.0, so the Corporate schema is still assembled from the documentation. The first run against the standard endpoint changed a signature and five enums, and the same may happen here. Until that run, these change in a minor release, recorded in the changelog and in UPGRADE.md, and this section shrinks as each is verified (#48).

Autentique::corporate(), Autentique::oauth() and Autentique::withToken() themselves are stable.

What is not public

  • The private methods of the manager and the provider.
  • Anything under tests/, which never ships.

Version 1.0.0. Released under the MIT License.