approve static method
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',
});
}
});