approve static method

Future<Response> approve(
  1. Request request
)

POST /oauth/authorize: the signed-in person's answer, as a form with the authorization parameters and decision=approve or deny. Answers {"redirect_to": ...} for the consent screen to navigate to, because a script following a redirect to the partner's origin could not read it.

CSRF is the generated route's to check, as on every other POST.

Implementation

static Future<Response> approve(Request request) => _guard(() async {
  final DVOAuthProvider? provider = await _provider();
  if (provider == null) return _notServed();
  final _Form form = await _form(request, allow: 'GET, POST');
  final Response? refused = form.refused;
  if (refused != null) return refused;
  final String? userId = await resolveUser?.call(request);
  if (userId == null || userId.isEmpty) {
    return _json(401, const <String, Object?>{
      'error': 'login_required',
      'error_description': 'sign in to answer this request',
    });
  }
  final _Validated v = await _validate(provider, <String, List<String>>{
    for (final MapEntry<String, String> e in form.fields.entries)
      e.key: <String>[e.value],
  });
  final DVAuthorizationRequest? valid = v.request;
  if (valid == null) return _validationError(v);
  switch (form.fields['decision']) {
    case 'approve':
      final DVIssuedAuthorizationCode issued = await provider.approve(
        valid,
        userId: userId,
        tenant: const DVTenants().currentTenant,
      );
      return _json(200, <String, Object?>{
        'redirect_to': issued.redirect.toString(),
      });
    case 'deny':
      return _json(200, <String, Object?>{
        'redirect_to': _errorRedirect(
          valid.redirectUri,
          'access_denied',
          'the request was declined',
          valid.state,
        ),
      });
    default:
      return _json(400, const <String, Object?>{
        'error': 'invalid_request',
        'error_description': 'decision is approve or deny',
      });
  }
});