UNPKG

mcp-quiz-server

Version:

🧠 AI-Powered Quiz Management via Model Context Protocol (MCP) - Create, manage, and take quizzes directly from VS Code, Claude, and other AI agents.

216 lines • 7.22 kB
export class SettingsService { constructor() { this.listeners = new Set(); this.STORAGE_KEY = 'quiz-app-settings'; this.SESSION_KEY = 'quiz-app-session'; this.settings = this.getDefaultSettings(); this.loadSettings(); this.validateSession(); } static getInstance() { if (!SettingsService.instance) { SettingsService.instance = new SettingsService(); } return SettingsService.instance; } getDefaultSettings() { return { ui: { hideDisabledNavButtons: false, hideAllNavButtons: false, autoAdvanceQuestions: false, clickToAdvance: false, showContinueButton: true, announceSelections: true, selectionFeedbackDuration: 2000, showQuestionNumbers: true, enableAnimations: true, defaultViewMode: 'list', sidebarExpanded: true, theme: 'light', accessibilityMode: false }, quiz: { showHints: false, confirmBeforeSubmit: true, highlightAnsweredQuestions: true, timerEnabled: false, maxAttempts: 3 }, user: { role: 'guest', permissions: ['view'], sessionTimeout: 3600000, lastLoginTime: Date.now() } }; } getSettings() { return { ...this.settings }; } updateSettings(updates) { if (!this.hasPermission('modify_settings')) { throw new Error('Insufficient permissions to modify settings'); } this.settings = this.mergeDeep(this.settings, updates); this.saveSettings(); this.notifyListeners(); } updateUISettings(uiSettings) { this.updateSettings({ ui: { ...this.settings.ui, ...uiSettings } }); } updateQuizSettings(quizSettings) { this.updateSettings({ quiz: { ...this.settings.quiz, ...quizSettings } }); } resetToDefaults() { if (this.settings.user.role !== 'admin') { throw new Error('Only administrators can reset settings to defaults'); } const currentUser = this.settings.user; this.settings = this.getDefaultSettings(); this.settings.user = currentUser; this.saveSettings(); this.notifyListeners(); } subscribe(callback) { this.listeners.add(callback); return () => { this.listeners.delete(callback); }; } authenticateUser(username, password) { const users = { 'admin': { password: 'admin123', role: 'admin', permissions: ['view', 'modify_settings', 'admin'] }, 'user': { password: 'user123', role: 'user', permissions: ['view', 'modify_settings'] }, 'guest': { password: '', role: 'guest', permissions: ['view'] } }; const user = users[username]; if (user && (user.password === password || username === 'guest')) { this.settings.user = { role: user.role, permissions: user.permissions, sessionTimeout: 3600000, lastLoginTime: Date.now() }; this.saveSession(); this.saveSettings(); return true; } return false; } logout() { this.settings.user = { role: 'guest', permissions: ['view'], sessionTimeout: 3600000, lastLoginTime: Date.now() }; this.clearSession(); this.saveSettings(); this.notifyListeners(); } hasPermission(permission) { return this.settings.user.permissions.includes(permission); } getCurrentRole() { return this.settings.user.role; } validateSession() { const now = Date.now(); const sessionAge = now - this.settings.user.lastLoginTime; if (sessionAge > this.settings.user.sessionTimeout) { this.logout(); } } notifyListeners() { this.listeners.forEach(callback => { try { callback(this.getSettings()); } catch (error) { console.error('Error in settings listener:', error); } }); } loadSettings() { try { const saved = localStorage.getItem(this.STORAGE_KEY); if (saved) { const parsed = JSON.parse(saved); this.settings = this.mergeDeep(this.getDefaultSettings(), parsed); } } catch (error) { console.warn('Failed to load settings from localStorage:', error); this.settings = this.getDefaultSettings(); } } saveSettings() { try { localStorage.setItem(this.STORAGE_KEY, JSON.stringify(this.settings)); } catch (error) { console.error('Failed to save settings to localStorage:', error); } } saveSession() { try { const sessionData = { role: this.settings.user.role, lastLoginTime: this.settings.user.lastLoginTime }; localStorage.setItem(this.SESSION_KEY, JSON.stringify(sessionData)); } catch (error) { console.error('Failed to save session:', error); } } clearSession() { try { localStorage.removeItem(this.SESSION_KEY); } catch (error) { console.error('Failed to clear session:', error); } } mergeDeep(target, source) { const result = { ...target }; for (const key in source) { if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) { result[key] = this.mergeDeep(result[key] || {}, source[key]); } else { result[key] = source[key]; } } return result; } get hideDisabledNavButtons() { return this.settings.ui.hideDisabledNavButtons; } get autoAdvanceQuestions() { return this.settings.ui.autoAdvanceQuestions; } get enableAnimations() { return this.settings.ui.enableAnimations; } get defaultViewMode() { return this.settings.ui.defaultViewMode; } get showContinueButton() { return this.settings.ui.showContinueButton; } get announceSelections() { return this.settings.ui.announceSelections; } get selectionFeedbackDuration() { return this.settings.ui.selectionFeedbackDuration; } get theme() { return this.settings.ui.theme; } get isTimerEnabled() { return this.settings.quiz.timerEnabled; } } //# sourceMappingURL=SettingsService-complex.js.map