drupal_request.dart 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Automatic FlutterFlow imports
  2. import '/backend/schema/structs/index.dart';
  3. import '/flutter_flow/flutter_flow_theme.dart';
  4. import '/flutter_flow/flutter_flow_util.dart';
  5. import 'index.dart'; // Imports other custom actions
  6. import '/flutter_flow/custom_functions.dart'; // Imports custom functions
  7. import 'package:flutter/material.dart';
  8. // Begin custom action code
  9. // DO NOT REMOVE OR MODIFY THE CODE ABOVE!
  10. import 'dart:async';
  11. import 'dart:convert';
  12. import 'package:http/http.dart' as http;
  13. Future<dynamic> drupalRequest(
  14. String method,
  15. String url,
  16. String sessionName,
  17. String sessionId,
  18. String token,
  19. String body,
  20. ) async {
  21. try {
  22. final ingevoerdeUrl = url.trim();
  23. final apiBase = FFAppState().apiBaseUrl.trim().isEmpty
  24. ? 'https://uitgaanskrant.com'
  25. : FFAppState().apiBaseUrl.trim();
  26. url = (ingevoerdeUrl.startsWith('http://') ||
  27. ingevoerdeUrl.startsWith('https://'))
  28. ? ingevoerdeUrl
  29. : apiBase +
  30. (ingevoerdeUrl.startsWith('/') ? ingevoerdeUrl : '/$ingevoerdeUrl');
  31. //--------------------------------------------------
  32. // Headers
  33. //--------------------------------------------------
  34. final headers = <String, String>{
  35. 'Accept': 'application/json',
  36. 'Content-Type': 'application/json',
  37. };
  38. if (sessionName.trim().isNotEmpty && sessionId.trim().isNotEmpty) {
  39. headers['Cookie'] = '$sessionName=$sessionId';
  40. }
  41. if (token.trim().isNotEmpty) {
  42. headers['X-CSRF-Token'] = token;
  43. }
  44. //--------------------------------------------------
  45. // DEBUG
  46. //--------------------------------------------------
  47. print('========================================');
  48. print('DRUPAL REQUEST');
  49. print('Method : $method');
  50. print('URL : $url');
  51. print('Headers');
  52. headers.forEach((k, v) => print('$k: $v'));
  53. if (body.isNotEmpty) {
  54. print('Body');
  55. print(body);
  56. }
  57. print('========================================');
  58. //--------------------------------------------------
  59. // Request
  60. //--------------------------------------------------
  61. http.Response response;
  62. switch (method.toUpperCase()) {
  63. case 'POST':
  64. response = await http
  65. .post(
  66. Uri.parse(url),
  67. headers: headers,
  68. body: body,
  69. )
  70. .timeout(const Duration(seconds: 30));
  71. break;
  72. case 'PUT':
  73. response = await http
  74. .put(
  75. Uri.parse(url),
  76. headers: headers,
  77. body: body,
  78. )
  79. .timeout(const Duration(seconds: 30));
  80. break;
  81. case 'DELETE':
  82. response = await http
  83. .delete(
  84. Uri.parse(url),
  85. headers: headers,
  86. body: body,
  87. )
  88. .timeout(const Duration(seconds: 30));
  89. break;
  90. default:
  91. response = await http
  92. .get(
  93. Uri.parse(url),
  94. headers: headers,
  95. )
  96. .timeout(const Duration(seconds: 30));
  97. }
  98. //--------------------------------------------------
  99. // DEBUG RESPONSE
  100. //--------------------------------------------------
  101. print('========================================');
  102. print('STATUS : ${response.statusCode}');
  103. print('RESPONSE HEADERS');
  104. response.headers.forEach((k, v) => print('$k: $v'));
  105. print('BODY');
  106. print(response.body);
  107. print('========================================');
  108. //--------------------------------------------------
  109. // JSON of tekst
  110. //--------------------------------------------------
  111. dynamic data;
  112. try {
  113. data = jsonDecode(response.body);
  114. } catch (_) {
  115. data = response.body;
  116. }
  117. if (response.statusCode >= 200 && response.statusCode < 300) {
  118. return data;
  119. }
  120. //--------------------------------------------------
  121. // Sessie verlopen? (toegevoegd 2026-09-20, taak C)
  122. //--------------------------------------------------
  123. // Alleen relevant als we zélf een cookie meestuurden: zonder cookie is een
  124. // 403 gewoon "dit endpoint vereist inloggen", niet "je sessie is weg".
  125. //
  126. // Drupal Services antwoordt bij een weggevallen sessie met 401, of met 403
  127. // plus het woord "anonymous" ("Toegang geweigerd voor gebruiker anonymous").
  128. // Een 403 zónder dat woord is een rechtenkwestie -- dan mag de gebruiker
  129. // niet uitgelogd worden.
  130. if (headers.containsKey('Cookie') &&
  131. (response.statusCode == 401 ||
  132. (response.statusCode == 403 &&
  133. response.body.toLowerCase().contains('anonymous')))) {
  134. print('SESSIE VERLOPEN -> lokale sessie wissen');
  135. // Exact dezelfde velden als de uitlogknop op Favorieten, zodat de app in
  136. // dezelfde uitgelogde staat komt. delete*() wist secure storage, de
  137. // toewijzing eronder de waarde in het geheugen.
  138. FFAppState().deleteUserSessionid();
  139. FFAppState().deleteUserSessionname();
  140. FFAppState().deleteUserToken();
  141. FFAppState().deleteUserName();
  142. FFAppState().deleteUserMail();
  143. FFAppState().deleteUserUid();
  144. // update() en niet de losse setters: alléén update() roept
  145. // notifyListeners() aan, en daar hangt VerbindingsBanner aan.
  146. FFAppState().update(() {
  147. FFAppState().userSessionid = '';
  148. FFAppState().userSessionname = '';
  149. FFAppState().userToken = '';
  150. FFAppState().userName = '';
  151. FFAppState().userMail = '';
  152. FFAppState().userUid = 0;
  153. FFAppState().sessieVerlopen = true;
  154. });
  155. }
  156. // De returnvorm blijft bewust een lege lijst: alle aanroepers doen blind
  157. // .toList() op het resultaat, dus een Map laat ze crashen.
  158. return [];
  159. } on TimeoutException {
  160. return [];
  161. } catch (e, stack) {
  162. print(e);
  163. print(stack);
  164. return [];
  165. }
  166. }
  167. // Set your action name, define your arguments and return parameter,
  168. // and then add the boilerplate code using the `</>` button on the right!