83 lines
2.5 KiB
Dart
83 lines
2.5 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:shelf/shelf.dart';
|
|
|
|
import '../cors_headers.dart';
|
|
import '../firebase_auth.dart';
|
|
import '../question_source_preferences.dart';
|
|
import '../question_source_preferences_db.dart';
|
|
|
|
const String questionSourcesBasePath = '/v1/me/question-sources';
|
|
|
|
Handler questionSourceHandler({
|
|
required QuestionSourcePreferencesDb db,
|
|
required FirebaseAuthVerifier auth,
|
|
}) {
|
|
return (Request request) async {
|
|
if (request.method == 'OPTIONS') {
|
|
return Response.ok(
|
|
'',
|
|
headers: apiCorsHeaders(methods: 'GET, PUT, OPTIONS'),
|
|
);
|
|
}
|
|
|
|
if (request.requestedUri.path != questionSourcesBasePath) {
|
|
return _jsonResponse(404, <String, dynamic>{'error': 'Not found'});
|
|
}
|
|
|
|
final String? firebaseUid = await auth.verifyBearerToken(
|
|
request.headers['Authorization'] ?? request.headers['authorization'],
|
|
);
|
|
if (firebaseUid == null) {
|
|
return _jsonResponse(401, <String, dynamic>{'error': 'Unauthorized'});
|
|
}
|
|
|
|
try {
|
|
if (request.method == 'GET') {
|
|
final List<ResolvedQuestionSourcePreference> sources =
|
|
await db.getResolved(firebaseUid);
|
|
return _jsonResponse(
|
|
200,
|
|
QuestionSourcePreferences.toApiPayload(sources: sources),
|
|
);
|
|
}
|
|
|
|
if (request.method == 'PUT') {
|
|
final String body = await request.readAsString();
|
|
final Map<String, dynamic> json =
|
|
jsonDecode(body) as Map<String, dynamic>;
|
|
final List<Map<String, dynamic>> stored =
|
|
QuestionSourcePreferences.parsePutBody(json);
|
|
final List<ResolvedQuestionSourcePreference> saved =
|
|
await db.save(firebaseUid, stored);
|
|
return _jsonResponse(
|
|
200,
|
|
QuestionSourcePreferences.toApiPayload(
|
|
sources: saved,
|
|
updatedAt: DateTime.now().toUtc(),
|
|
),
|
|
);
|
|
}
|
|
|
|
return _jsonResponse(405, <String, dynamic>{'error': 'Method not allowed'});
|
|
} on QuestionSourceValidationException catch (e) {
|
|
return _jsonResponse(400, <String, dynamic>{'error': e.message});
|
|
} catch (e, st) {
|
|
stderr.writeln('Question source handler error: $e\n$st');
|
|
return _jsonResponse(500, <String, dynamic>{'error': 'Internal error'});
|
|
}
|
|
};
|
|
}
|
|
|
|
Response _jsonResponse(int status, Map<String, dynamic> body) {
|
|
return Response(
|
|
status,
|
|
body: jsonEncode(body),
|
|
headers: <String, String>{
|
|
...apiCorsHeaders(methods: 'GET, PUT, OPTIONS'),
|
|
'Content-Type': 'application/json',
|
|
},
|
|
);
|
|
}
|