106 lines
3.5 KiB
Dart
106 lines
3.5 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:relic/relic.dart';
|
|
|
|
import 'config/config.dart';
|
|
import 'src/auth/auth_middleware.dart';
|
|
import 'src/gateway/gateway_handlers.dart';
|
|
import 'src/handlers/auth_handlers.dart';
|
|
import 'src/handlers/channel_handlers.dart';
|
|
import 'src/handlers/dev_db_handlers.dart';
|
|
import 'src/handlers/message_handlers.dart';
|
|
import 'src/handlers/public_handlers.dart';
|
|
import 'src/handlers/settings_handlers.dart';
|
|
import 'src/handlers/upload_handlers.dart';
|
|
import 'src/state/app_state.dart';
|
|
|
|
RelicApp? _currentApp;
|
|
|
|
Future<void> startServer() async {
|
|
await _currentApp?.close();
|
|
|
|
_currentApp = RelicApp()
|
|
// ============ PUBLIC ENDPOINTS (no auth) ============
|
|
|
|
// Auth
|
|
..post('/auth/register', registerHandler)
|
|
..post('/auth/login', loginHandler)
|
|
..post('/auth/join', joinServerHandler)
|
|
|
|
// Public identity verification (for cross-server)
|
|
..get('/.well-known/users/:username', publicUserHandler)
|
|
..get('/.well-known/verify/:userId', publicVerifyHandler)
|
|
..get('/.well-known/server', publicServerInfoHandler)
|
|
..get('/uploads/:fileName', getUploadFileHandler)
|
|
..get('/attachments/:attachmentId', getAttachmentHandler)
|
|
..get('/avatars/:userId', getAvatarAliasHandler)
|
|
..get('/icons/:serverId', getServerIconAliasHandler)
|
|
..get('/banners/:serverId', getServerBannerAliasHandler)
|
|
..get('/gateway', gatewayHandler)
|
|
|
|
// ============ PROTECTED ENDPOINTS (requires auth) ============
|
|
..use('/api', jwtMiddleware)
|
|
|
|
// Current user
|
|
..get('/api/me', getMeHandler)
|
|
..patch('/api/me', updateProfileHandler)
|
|
..put('/api/me/avatar', setAvatarHandler)
|
|
|
|
// Server settings
|
|
..get('/api/server/settings', getServerSettingsHandler)
|
|
..patch('/api/server/settings', patchServerSettingsHandler)
|
|
..put('/api/server/icon', setServerIconHandler)
|
|
..put('/api/server/banner', setServerBannerHandler)
|
|
|
|
// Dev DB tools (testing only, admin only, requires config flag)
|
|
..get('/api/dev/db/snapshot', getDevDbSnapshotHandler)
|
|
..post('/api/dev/db/reset', resetDevDbHandler)
|
|
..post('/api/dev/users/promote-admin', promoteUserToAdminHandler)
|
|
..post('/api/dev/users/demote-admin', demoteUserFromAdminHandler)
|
|
|
|
// Channels
|
|
..get('/api/channels', getChannelsHandler)
|
|
..post('/api/channels', createChannelHandler)
|
|
..get('/api/channels/:channelId', getChannelHandler)
|
|
|
|
// Messages
|
|
..get('/api/messages', getMessagesHandler)
|
|
..get('/api/channels/:channelId/media', getChannelMediaHandler)
|
|
..post('/api/uploads/init', initUploadHandler)
|
|
..put('/api/uploads/:uploadId', completeUploadHandler)
|
|
..post('/api/uploads', uploadFileHandler)
|
|
..post('/api/messages', sendMessageHandler)
|
|
..put('/api/messages/:messageId', editMessageHandler)
|
|
..delete('/api/messages/:messageId', deleteMessageHandler)
|
|
|
|
// ============ LOGGING & FALLBACK ============
|
|
..use('/', logRequests())
|
|
..fallback = respondWith((_) => Response.notFound());
|
|
|
|
print('');
|
|
print('🚀 Server starting...');
|
|
print('Bind: ${'${Config.bindHost}:${Config.bindPort}'.padRight(34)}');
|
|
print('Public URL: ${Config.publicBaseUrl.padRight(26)}');
|
|
print('');
|
|
|
|
final bindAddress = InternetAddress.tryParse(Config.bindHost) ?? (await InternetAddress.lookup(Config.bindHost)).first;
|
|
|
|
await _currentApp!.serve(
|
|
address: bindAddress,
|
|
port: Config.bindPort,
|
|
);
|
|
}
|
|
|
|
Future<void> stopServer() async {
|
|
await _currentApp?.close();
|
|
_currentApp = null;
|
|
}
|
|
|
|
void main() async {
|
|
Config.initialize();
|
|
|
|
initializeStore();
|
|
|
|
await startServer();
|
|
}
|