# Authentication System `CAndruavAuth` is a singleton class handling authentication with the Andruav/Ardupilot-Cloud backend. It manages login, logout, access code generation, and permission validation for the web-based drone control client. ## Definition `CAndruavAuth` is a JavaScript class responsible for authenticating users in the Andruav web client, a system used to interact with drones via the Ardupilot-Cloud platform. It uses HTTP requests to communicate with a backend authentication server and maintains session state, permissions, and retry logic. The class follows the **singleton pattern** via the static `getInstance()` method, ensuring only one instance exists across the application. This is crucial for maintaining consistent authentication state. ```javascript class CAndruavAuth { constructor() { this.m_username = ''; this.m_accesscode = ''; this.m_retry_login = true; this.m_retry_handle = null; window._localserverIP = '127.0.0.1'; window._localserverPort = 9211; this._m_ver = '5.0.0'; this.m_auth_ip = js_siteConfig.CONST_TEST_MODE ? js_siteConfig.CONST_TEST_MODE_IP : js_siteConfig.CONST_PROD_MODE_IP; this._m_auth_port = js_siteConfig.CONST_TEST_MODE ? js_siteConfig.CONST_TEST_MODE_PORT : js_siteConfig.CONST_PROD_MODE_PORT; this._m_auth_ports = this._m_auth_port; // Legacy this._m_perm = 0; this._m_permissions_ = ''; this._m_session_ID = null; this._m_logined = false; this.C_ERR_SUCCESS_DISPLAY_MESSAGE = 1001; // Legacy } static getInstance() { if (!CAndruavAuth.instance) { CAndruavAuth.instance = new CAndruavAuth(); } return CAndruavAuth.instance; } // Core methods: // fn_do_loginAccount() – authenticate user // fn_do_logoutAccount() – terminate session // fn_generateAccessCode() – create access tokens // fn_regenerateAccessCode() – refresh tokens // Permission checks: fn_do_canGCS(), fn_do_canControl(), etc. } ``` - **Type**: Class (singleton) - **Purpose**: Centralized authentication and session management - **Key fields**: - `_m_session_ID`: Stores active session token - `_m_logined`: Boolean indicating login state - `_m_perm`: Bitmask of user permissions - `_m_permissions_`: Hex string representation of permissions - **Key methods**: - `fn_do_loginAccount()`: Logs in using email and access code - `fn_do_logoutAccount()`: Ends session - `fn_generateAccessCode()` / `fn_regenerateAccessCode()`: Manage access tokens - `fn_do_can*()`: Permission checks using bitmasks - **Side effects**: Dispatches events via `js_eventEmitter`, makes HTTP requests, sets timeouts for retry - **Dependencies**: - `js_siteConfig`: Determines auth server IP/port based on test/prod mode - `js_andruavMessages`: Contains constants for API endpoints and permission flags - `js_eventEmitter`: Used to notify other parts of the app about auth state changes ## Example Usages The most common usage is logging in a user via email and access code (password), then checking their permissions. ```javascript async fn_do_loginAccount(p_userName, p_accessCode) { js_eventEmitter.fn_dispatch(js_event.EE_Auth_Login_In_Progress, null); if (!this.#validateEmail(p_userName) || !p_accessCode) { this._m_logined = false; js_eventEmitter.fn_dispatch(js_event.EE_Auth_BAD_Logined, { /* error */ }); return false; } const url = this.#getBaseUrl(js_andruavMessages.CONST_WEB_LOGIN_COMMAND); const keyValues = { [js_andruavMessages.CONST_ACCOUNT_NAME_PARAMETER]: p_userName, [js_andruavMessages.CONST_ACCESS_CODE_PARAMETER]: p_accessCode, [js_andruavMessages.CONST_APP_GROUP_PARAMETER]: '1', [js_andruavMessages.CONST_APP_NAME_PARAMETER]: 'de', [js_andruavMessages.CONST_APP_VER_PARAMETER]: this._m_ver, [js_andruavMessages.CONST_EXTRA_PARAMETER]: 'DRONE ENGAGE Web Client', [js_andruavMessages.CONST_ACTOR_TYPE]: AUTH_GCS_TYPE, }; const probeResult = await this.fn_probeServer(this.#getHealthURL()); if (!probeResult.success) { // Handle server unreachable or SSL error return false; } try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(keyValues) }).then(res => res.json()); if (response.e === js_andruavMessages.CONST_ERROR_NON) { this._m_session_ID = response.session_id; this._m_permissions_ = response.permissions || DEFAULT_PERMISSIONS; this._m_perm = parseInt(this._m_permissions_, 16); this._m_logined = true; js_eventEmitter.fn_dispatch(js_event.EE_Auth_Logined, { /* success */ }); return true; } else { // Handle login failure } } catch (error) { // Handle network/SSL errors } // Schedule retry if enabled if (this.m_retry_login) { this.m_retry_handle = setTimeout(() => { this.fn_do_loginAccount(this.m_username, this.m_accesscode); }, AUTH_REQUEST_TIMEOUT); } return false; } ``` Another key usage is checking user permissions after login: ```javascript fn_do_canGCS() { return (this._m_perm & js_andruavMessages.CONST_ALLOW_GCS) === js_andruavMessages.CONST_ALLOW_GCS; } ``` This uses bitwise AND to check if the `CONST_ALLOW_GCS` flag is set in the user's permission bitmask. The exported instance `js_andruavAuth` is used throughout the codebase: ```javascript export const js_andruavAuth = CAndruavAuth.getInstance(); ``` This allows any module to import and use the same auth instance: ```javascript import { js_andruavAuth } from './js_andruav_auth.js'; if (js_andruavAuth.fn_logined()) { console.log("User is logged in"); } ``` **Usage Summary**: `CAndruavAuth` is central to the web client's security model. It is used in login forms, permission gates for drone control features, and automated token management. Its singleton nature ensures consistent state, and its event dispatching allows UI components to react to login/logout events. ## Notes - **Automatic retry on login failure**: If `m_retry_login` is enabled (default), failed login attempts trigger a retry after `AUTH_REQUEST_TIMEOUT` (10 seconds). This helps recover from transient network issues. - **Health check before login**: The class probes the server's `/health` endpoint before attempting login, improving error diagnosis (e.g., distinguishing between network issues and bad credentials). - **SSL error detection**: It attempts to detect SSL/TLS issues by inspecting error messages like `ERR_CERT`, providing more specific feedback than generic network errors. - **Legacy support**: Fields like `_m_auth_ports` and `C_ERR_SUCCESS_DISPLAY_MESSAGE` suggest backward compatibility with older versions of the system. ## See Also - `js_andruavAuth`: The exported singleton instance of `CAndruavAuth`, used globally across the app. - `js_siteConfig`: Provides configuration for test vs production environments, determining which auth server to connect to. - `js_andruavMessages`: Contains constants like `CONST_WEB_LOGIN_COMMAND`, `CONST_ALLOW_GCS`, and other protocol-level definitions used by `CAndruavAuth`. - `js_eventEmitter`: Event system used to broadcast authentication state changes (e.g., `EE_Auth_Logined`, `EE_Auth_BAD_Logined`). - `AUTH_GCS_TYPE`: Constant `'g'` indicating the client is a Ground Control Station, sent during login to identify the actor type.