Client Security

371 visitas Markdown

The five endpoints that manage the password, verification, two-step sign-in and the security rules set on a client.

Overview

These five endpoints carry the security decisions an operator applies to a client account: setting the password, marking a field verified, turning on two-step verification, tightening sign-in and payment rules, and limiting support access.

None of them ask the client anything. They all apply directly, which is why a key carrying these endpoints is worth keeping narrow.

Reference

Changing the Password

put/api/v1/admin/clients/{id}/password
Clients/SetClientPassword admin no old password asked

Sets the client's password directly. The current one is not asked for.

Body 2
passwordstringrequiredThe new password. At least options/password-length characters; defaults to 6.
password_confirmationstringIf sent, it must match password exactly. Leave it out and no check is made.
Response fields data — 1
changedboolWhether the password was changed.
Errors 5
not_found404No such client.
password_required422The password is empty.
password_too_short422The password is below the minimum length. The limit comes back in error.details.min.
password_mismatch422The confirmation does not match the password.
insufficient_scope403The key lacks the required scope.
Request
curl -X PUT 'https://panel.example.com/api/v1/admin/clients/42/password' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"password":"Str0ngP@ssw0rd","password_confirmation":"Str0ngP@ssw0rd"}'
const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/password', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    password: 'Str0ngP@ssw0rd',
    password_confirmation: 'Str0ngP@ssw0rd',
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/password');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'password'              => $newPassword,
        'password_confirmation' => $newPassword,
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
$response = Api::Clients()->SetClientPassword([
    'id'       => 42,
    'password' => $newPassword,
]);

Verifying Email and Phone

post/api/v1/admin/clients/{id}/verify
Clients/VerifyClient admin

Marks a field as verified. No code is sent to the client; the flag is set directly.

Body 1
typestringrequiredemail or phone.
Response fields data — 2
verifiedboolWhether the verification was applied.
typestringThe field that was verified: email or phone.
Errors 3
not_found404No such client.
type_invalid422type is neither of the two values.
insufficient_scope403The key lacks the required scope.
Request
curl -X POST 'https://panel.example.com/api/v1/admin/clients/42/verify' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"type":"email"}'
const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/verify', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ type: 'email' }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/verify');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['type' => 'email']),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// You set the flag here after running your own verification flow.
$response = Api::Clients()->VerifyClient([
    'id'   => 42,
    'type' => 'email',
]);

Two-Step Verification

put/api/v1/admin/clients/{id}/2fa
Clients/SetClient2fa admin

Turns the client's two-step verification on or off.

Body 2
enabledboolrequiredTurns it on or off.
methodstringName of the Authentication module to use, for example GoogleAuthenticator. Required only when enabling; not needed to disable.
Response fields data — 2
enabledboolThe two-step state as it now stands.
methodstringThe module that was selected. Comes back only when enabling.
Errors 3
not_found404No such client.
method_required422method was missing on an enable request.
insufficient_scope403The key lacks the required scope.
Request
curl -X PUT 'https://panel.example.com/api/v1/admin/clients/42/2fa' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"enabled":true,"method":"GoogleAuthenticator"}'
const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/2fa', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ enabled: true, method: 'GoogleAuthenticator' }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/2fa');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'enabled' => true,
        'method'  => 'GoogleAuthenticator',
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// You do not need to send a method when turning it off.
$response = Api::Clients()->SetClient2fa([
    'id'      => 42,
    'enabled' => false,
]);

Security Settings

patch/api/v1/admin/clients/{id}/security-settings
Clients/UpdateClientSecuritySettings admin

Changes the security rules that apply to this client. Only the fields you send change.

Body 6
block_proxyboolBlocks sign-in from behind a proxy.
allow_proxyboolExempts this client from the proxy check.
require_birthdayboolMakes the date of birth required.
require_adult_ageboolRequires an over-18 check.
force_document_filtersint[]Ids of the document verification filters to enforce. List: clients/document-filters.
blocked_gatewaysstring[]Keys of the payment methods closed to this client.
Response fields data — 6
block_proxyboolWhether sign-in from behind a proxy is blocked. The whole state comes back, not only the part you sent.
allow_proxyboolWhether the client is exempt from the proxy check.
require_birthdayboolWhether the date of birth is required.
require_adult_ageboolWhether the over-18 check is on.
force_document_filtersint[]Ids of the enforced document verification filters.
blocked_gatewaysstring[]Keys of the payment methods closed to this client.
Errors 2
not_found404No such client.
insufficient_scope403The key lacks the required scope.
Request
curl -X PATCH 'https://panel.example.com/api/v1/admin/clients/42/security-settings' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"block_proxy":true,"blocked_gateways":["PayPal"]}'
const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/security-settings', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ block_proxy: true, blocked_gateways: ['PayPal'] }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/security-settings');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PATCH',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'block_proxy'      => true,
        'blocked_gateways' => ['PayPal'],
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
$response = Api::Clients()->UpdateClientSecuritySettings([
    'id'          => 42,
    'block_proxy' => true,
]);

Support Settings

patch/api/v1/admin/clients/{id}/support-settings
Clients/UpdateClientSupportSettings admin

Restricts or closes the client's ability to open support tickets.

Body 2
ticket_restrictedboolRestricts opening tickets.
ticket_blockedboolBlocks opening tickets outright.
Response fields data — 2
ticket_restrictedboolWhether opening tickets is restricted. The whole state comes back, not only the part you sent.
ticket_blockedboolWhether opening tickets is blocked.
Errors 2
not_found404No such client.
insufficient_scope403The key lacks the required scope.
Request
curl -X PATCH 'https://panel.example.com/api/v1/admin/clients/42/support-settings' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"ticket_restricted":true}'
const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/support-settings', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ ticket_restricted: true }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/support-settings');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PATCH',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['ticket_restricted' => true]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
$response = Api::Clients()->UpdateClientSupportSettings([
    'id'                => 42,
    'ticket_restricted' => true,
]);

Pitfalls

Changing the password asks for no old one

The endpoint is an operator tool: it writes a new password without knowing the current one. The flow where a client changes their own password is a different one and lives in the Client API.

Verifying sends no code

verify only sets the flag; no email or SMS reaches the client. Call it after your own verification flow has run, not instead of it.

The two proxy fields are opposites

block_proxy blocks and allow_proxy exempts. Sending both as on leaves a contradictory state; send only the one you mean.

¿Le ha resultado útil?

¡Gracias por sus comentarios!

¿Todavía necesita ayuda?

Nuestro equipo de soporte está disponible las 24 horas para ayudarle con lo que no encuentre aquí.