All checks were successful
PR Checks / android-build (pull_request) Successful in 20m34s
Add the app client for the Mobile SSO Authorization Bridge (PLAN.md §4.2): native "Sign in with <provider>" without shipping any OAuth secret. - Pkce: pure-JVM RFC 7636 S256 verifier/challenge + CSRF state, encoded to match the backend's base64url(SHA-256) exactly. - SsoAuthManager (Singleton): mints PKCE+state, builds the /auth/mobile/sso/start URL for a Custom Tab, verifies the returned state, exchanges the one-time code with the stashed verifier, and drives the existing SessionManager.onSignedIn — no new token-storage or refresh code. Pending flow is in-memory (fails closed on process death). Exposes an outcome StateFlow the login screen consumes. - SsoApi + DTOs: GET /auth/providers discovery and POST /auth/mobile/sso/exchange (tagged NO_SESSION so a credential 401 isn't read as an expired session). - MainActivity: runicgateway://auth/callback intent-filter + singleTop; parses the callback Uri (the Android edge) and hands raw params to SsoAuthManager. - LoginScreen/ViewModel: render a button per discovered provider, opening the bridge in a Custom Tab; fall back to the website login hand-off when none. Additive — no other screen's data flow changes; no backend work. Custom scheme only for now (App Links deferred, APP_LINKS.md). Tests (JVM, +14): Pkce vector/charset, start-URL building, and the full complete() flow over a fake SsoApi + real SessionManager (success signs in; state mismatch / missing pending fail without exchanging; error callback → declined; 401 → expired-code; replay finds no pending). Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NgyHnrNa8WwG3doxvxjuCr
297 lines
20 KiB
XML
297 lines
20 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
|
||
<!--
|
||
All user-facing strings are externalized from day one (PLAN.md §2): English is
|
||
the only bundled locale, but the structure invites community translations.
|
||
No hardcoded UI strings in Kotlin.
|
||
-->
|
||
<resources>
|
||
<!-- Fixed launcher name, baked at build even though in-app branding is per-shard (PLAN.md §13). -->
|
||
<string name="app_name">Runic Gateway</string>
|
||
|
||
<!-- ── Shared actions / errors ─────────────────────────────────────── -->
|
||
<string name="action_retry">Retry</string>
|
||
<string name="action_back">Back</string>
|
||
<string name="error_network">Can\'t reach the site. Check your connection and try again.</string>
|
||
<string name="error_not_found">This content couldn\'t be found.</string>
|
||
<string name="error_rate_limited">Too many requests. Please try again in a moment.</string>
|
||
<string name="error_shard_offline">The shard is offline right now.</string>
|
||
<string name="error_server">Something went wrong on the server. Please try again.</string>
|
||
|
||
<!-- ── First-run connect (§3) ──────────────────────────────────────── -->
|
||
<string name="connect_title">Connect to your shard</string>
|
||
<string name="connect_subtitle">Enter your shard\'s website address to get started.</string>
|
||
<string name="connect_url_label">Website address</string>
|
||
<string name="connect_url_hint">https://your-shard.example.com</string>
|
||
<string name="connect_button">Connect</string>
|
||
<string name="connect_connecting">Connecting…</string>
|
||
<string name="connect_error_blank">Enter a website address.</string>
|
||
<string name="connect_error_malformed">That doesn\'t look like a valid web address.</string>
|
||
<string name="connect_error_scheme">Only http and https addresses are supported.</string>
|
||
<string name="connect_error_insecure">A secure https address is required.</string>
|
||
<string name="connect_error_not_runic">That site isn\'t a Runic Gateway shard.</string>
|
||
<string name="connect_error_version">This app is out of date for that site (it speaks API %1$s). Update the app and try again.</string>
|
||
<string name="connect_error_unreachable">Couldn\'t reach that site. Check the address and your connection.</string>
|
||
<string name="connect_error_server">The site responded with an error (%1$d). Try again shortly.</string>
|
||
|
||
<!-- ── Navigation menu (§5) ────────────────────────────────────────── -->
|
||
<string name="nav_open_menu">Open navigation menu</string>
|
||
<string name="menu_home">Home</string>
|
||
<string name="menu_news">News</string>
|
||
<string name="menu_wiki">Wiki</string>
|
||
<string name="menu_shard">Shard</string>
|
||
<string name="menu_about">About</string>
|
||
<string name="menu_contact">Contact</string>
|
||
<string name="menu_account">My account</string>
|
||
<string name="menu_my_characters">My characters</string>
|
||
<string name="menu_my_vendors">My vendors</string>
|
||
<string name="menu_my_houses">My houses</string>
|
||
<string name="menu_sign_in">Sign in</string>
|
||
<string name="menu_sign_out">Sign out</string>
|
||
<string name="menu_change_server">Change server</string>
|
||
|
||
<!-- ── Auth: login (§4.1) ──────────────────────────────────────────── -->
|
||
<string name="login_title">Sign in</string>
|
||
<string name="login_subtitle">Sign in with your shard account.</string>
|
||
<string name="login_username">Username</string>
|
||
<string name="login_password">Password</string>
|
||
<string name="login_totp_code">Authentication code</string>
|
||
<string name="login_totp_hint">Enter the 6-digit code from your authenticator app.</string>
|
||
<string name="login_button">Sign in</string>
|
||
<string name="login_register">Create an account</string>
|
||
<string name="login_forgot">Forgot your password?</string>
|
||
<string name="login_sso">Sign in with Google or Discord (on the website)</string>
|
||
<!-- %1$s is the provider name, e.g. "Google" or "Discord" (native SSO, M9). -->
|
||
<string name="login_sso_provider">Sign in with %1$s</string>
|
||
<string name="login_error_credentials">Incorrect username or password.</string>
|
||
<string name="login_error_code">That code didn\'t match. Try the current code.</string>
|
||
<string name="login_error_rate_limited">Too many attempts. Please try again shortly.</string>
|
||
<string name="login_error_server">Something went wrong. Please try again.</string>
|
||
<string name="login_error_network">Can\'t reach the site. Check your connection and try again.</string>
|
||
<string name="login_error_sso">Couldn\'t complete that sign-in. Please try again.</string>
|
||
|
||
<!-- ── Auth: account (§5, §6.3) ────────────────────────────────────── -->
|
||
<string name="account_title">My account</string>
|
||
<string name="account_sign_out">Sign out</string>
|
||
<string name="account_sign_out_all">Sign out on all devices</string>
|
||
|
||
<!-- Username -->
|
||
<string name="account_username_title">Username</string>
|
||
<string name="account_username_action">Change username</string>
|
||
<string name="account_username_changed">Username updated.</string>
|
||
<string name="account_username_taken">That username is already taken.</string>
|
||
<string name="account_username_error">Couldn\'t change your username.</string>
|
||
|
||
<!-- Password -->
|
||
<string name="account_password_title">Password</string>
|
||
<string name="account_password_set_title">Set a password</string>
|
||
<string name="account_password_set_hint">Your account was created through a linked provider and has no password yet. Set one to also sign in with a username and password.</string>
|
||
<string name="account_password_current">Current password</string>
|
||
<string name="account_password_new">New password</string>
|
||
<string name="account_password_action">Change password</string>
|
||
<string name="account_password_set_action">Set password</string>
|
||
<string name="account_password_changed">Password changed.</string>
|
||
<string name="account_password_error">Couldn\'t change your password. Check your current password and try again.</string>
|
||
|
||
<!-- Two-factor -->
|
||
<string name="account_totp_title">Two-factor authentication</string>
|
||
<string name="account_totp_on">Enabled</string>
|
||
<string name="account_totp_off">Not enabled</string>
|
||
<string name="account_totp_scan">Scan this code with your authenticator app, then enter the current code.</string>
|
||
<string name="account_totp_qr_desc">Two-factor QR code</string>
|
||
<string name="account_totp_setup">Set up two-factor</string>
|
||
<string name="account_totp_confirm">Confirm & enable</string>
|
||
<string name="account_totp_cancel">Cancel</string>
|
||
<string name="account_totp_disable">Disable two-factor</string>
|
||
<string name="account_totp_enabled">Two-factor is now enabled.</string>
|
||
<string name="account_totp_disabled">Two-factor has been disabled.</string>
|
||
<string name="account_totp_code_error">That code isn\'t valid. Try the current code.</string>
|
||
<string name="account_totp_setup_error">Couldn\'t start two-factor setup.</string>
|
||
|
||
<!-- Linked identities -->
|
||
<string name="account_identities_title">Linked accounts</string>
|
||
<string name="account_identities_empty">No linked sign-in providers.</string>
|
||
<string name="account_identity_unlink">Unlink</string>
|
||
<string name="account_identity_unlinked">Account unlinked.</string>
|
||
<string name="account_identity_error">Couldn\'t unlink that account.</string>
|
||
|
||
<!-- ── Player: game-account linking (§6.3) ─────────────────────────── -->
|
||
<string name="player_link_title">Link your game account</string>
|
||
<string name="player_link_hint">In game, type [link to get a one-time code, then enter it here to see your characters, vendors and houses.</string>
|
||
<string name="player_link_code">Link code</string>
|
||
<string name="player_link_action">Link account</string>
|
||
<string name="player_link_ok">Account linked.</string>
|
||
<string name="player_link_bad_code">That code is unknown or has expired. Run [link in game for a new one.</string>
|
||
<string name="player_link_error">Couldn\'t link that code. Please try again.</string>
|
||
|
||
<string name="player_create_title">Create a game account</string>
|
||
<string name="player_create_account">Account name</string>
|
||
<string name="player_create_password">Password</string>
|
||
<string name="player_create_action">Create account</string>
|
||
<string name="player_create_ok">Game account created and linked.</string>
|
||
<string name="player_create_taken">That account name is already taken.</string>
|
||
<string name="player_create_capped">The account limit for your network has been reached.</string>
|
||
<string name="player_create_unavailable">Game-account signup isn\'t available right now.</string>
|
||
<string name="player_create_rejected">That account name or password wasn\'t accepted.</string>
|
||
<string name="player_create_error">Couldn\'t create that account. Please try again.</string>
|
||
|
||
<!-- ── Player: characters (§6.3) ───────────────────────────────────── -->
|
||
<string name="player_characters_empty">Link a game account above to see your characters.</string>
|
||
<string name="player_roster_loading">Loading…</string>
|
||
<string name="player_roster_empty">No characters on this account.</string>
|
||
<string name="player_char_unknown">Unknown</string>
|
||
<string name="player_char_online">Online</string>
|
||
<string name="player_char_offline">Offline</string>
|
||
|
||
<!-- Character sheet -->
|
||
<string name="player_char_governor">Governor of %1$s</string>
|
||
<string name="player_char_guildmaster">Guildmaster, %1$s</string>
|
||
<string name="player_char_attributes">Attributes</string>
|
||
<string name="player_char_vitals">Vitals</string>
|
||
<string name="player_char_str">STR</string>
|
||
<string name="player_char_dex">DEX</string>
|
||
<string name="player_char_int">INT</string>
|
||
<string name="player_char_hits">Hits</string>
|
||
<string name="player_char_mana">Mana</string>
|
||
<string name="player_char_stam">Stamina</string>
|
||
<string name="player_char_resistances">Resistances</string>
|
||
<string name="player_char_phys">Physical</string>
|
||
<string name="player_char_fire">Fire</string>
|
||
<string name="player_char_cold">Cold</string>
|
||
<string name="player_char_pois">Poison</string>
|
||
<string name="player_char_energy">Energy</string>
|
||
<string name="player_char_skills">Skills</string>
|
||
<string name="player_char_equipment">Equipment</string>
|
||
<string name="player_char_item">Item</string>
|
||
<string name="player_char_item_id">id %1$d</string>
|
||
<string name="player_char_item_hue">hue %1$d</string>
|
||
|
||
<!-- ── Player: vendors & sales (§6.3) ──────────────────────────── -->
|
||
<string name="player_sales_title">Recent sales</string>
|
||
<string name="player_sales_empty">No recent sales.</string>
|
||
<string name="player_gold_amount">%1$s gp</string>
|
||
<string name="player_vendors_no_accounts">Link a game account to see your vendors.</string>
|
||
<string name="player_vendors_empty">No vendors on this account.</string>
|
||
<string name="player_vendor_fallback">Player vendor</string>
|
||
<string name="player_vendor_hold">Holding %1$s gp</string>
|
||
<string name="player_vendor_no_listings">No items listed.</string>
|
||
<string name="player_listing_item">Item %1$d ×%2$d</string>
|
||
|
||
<!-- ── Player: houses (§6.3) ───────────────────────────────────────── -->
|
||
<string name="player_houses_empty">You don\'t have any houses on your linked accounts.</string>
|
||
<string name="player_house_fallback">A house</string>
|
||
<string name="player_house_stage">Status: %1$s</string>
|
||
<string name="role_player">Player</string>
|
||
<string name="role_moderator">Moderator</string>
|
||
<string name="role_editor">Editor</string>
|
||
<string name="role_admin">Administrator</string>
|
||
<string name="role_unknown">Signed in</string>
|
||
|
||
<!-- ── Home / status (§6.1) ────────────────────────────────────────── -->
|
||
<string name="home_status_live">Online</string>
|
||
<string name="home_status_maintenance">Under maintenance</string>
|
||
<string name="home_server_version">Server %1$s · API %2$s</string>
|
||
|
||
<!-- ── News & content (§6.1) ───────────────────────────────────────── -->
|
||
<string name="news_title">News & content</string>
|
||
<string name="news_cat_news">News</string>
|
||
<string name="news_cat_screenshots">Screenshots</string>
|
||
<string name="news_cat_five_on_friday">Five on Friday</string>
|
||
<string name="news_cat_newsletter">Newsletter</string>
|
||
<string name="news_empty">No posts here yet.</string>
|
||
|
||
<!-- ── Wiki (§6.1) ─────────────────────────────────────────────────── -->
|
||
<string name="wiki_title">Wiki</string>
|
||
<string name="wiki_search_hint">Search the wiki</string>
|
||
<string name="wiki_empty">No pages found.</string>
|
||
<string name="wiki_section_tags">Tags</string>
|
||
<string name="wiki_section_backlinks">Linked from</string>
|
||
|
||
<!-- ── Contact (§6.1) ──────────────────────────────────────────────── -->
|
||
<string name="contact_title">Contact</string>
|
||
<string name="contact_name">Your name</string>
|
||
<string name="contact_email">Your email</string>
|
||
<string name="contact_message">Message</string>
|
||
<string name="contact_send">Send message</string>
|
||
<string name="contact_sending">Sending…</string>
|
||
<string name="contact_sent">Message sent — thank you!</string>
|
||
<string name="contact_fallback">This site has no mailer configured. Email directly: %1$s</string>
|
||
<string name="contact_validation">Please fill in every field.</string>
|
||
<string name="contact_error">Couldn\'t send your message. Please try again.</string>
|
||
|
||
<!-- ── Shard hub & live feed (§6.2) ─────────────────────────────── -->
|
||
<string name="shard_live">Live</string>
|
||
<string name="shard_offline">Offline</string>
|
||
<string name="shard_status_online">Shard online</string>
|
||
<string name="shard_status_offline">Shard offline</string>
|
||
<string name="shard_online_count">%1$d players online</string>
|
||
<string name="shard_economy_gold">Gold supply: %1$s</string>
|
||
<string name="shard_section_staff">Staff online</string>
|
||
<string name="shard_section_activity">Live activity</string>
|
||
<string name="shard_feed_empty">No recent activity.</string>
|
||
<string name="shard_nav_champs">Champion spawns</string>
|
||
<string name="shard_nav_guilds">Guilds</string>
|
||
<string name="shard_nav_governors">Governors</string>
|
||
<string name="shard_nav_houses">Falling houses</string>
|
||
|
||
<!-- ── Champion spawns (§6.2) ──────────────────────────────────────── -->
|
||
<string name="champs_empty">No champion spawns are being tracked right now.</string>
|
||
<string name="champs_fallback_name">Champion spawn</string>
|
||
<string name="champ_level">Level %1$d</string>
|
||
<string name="champ_cooldown">Restarting</string>
|
||
|
||
<!-- ── Guilds (§6.2) ───────────────────────────────────────────────── -->
|
||
<string name="guilds_empty">No guilds are being tracked right now.</string>
|
||
<string name="guilds_fallback_name">Guild</string>
|
||
<string name="guilds_members">%1$d members</string>
|
||
<string name="guilds_leader">Led by %1$s</string>
|
||
<string name="guilds_alliance">Alliance: %1$s</string>
|
||
|
||
<!-- ── Governors (§6.2) ────────────────────────────────────────────── -->
|
||
<string name="governors_empty">No governors — this shard may not run the City Loyalty system.</string>
|
||
<string name="governor_current">Governed by %1$s</string>
|
||
<string name="governor_none">No governor</string>
|
||
<string name="governor_election">Election: %1$s</string>
|
||
<string name="governor_history">Term history</string>
|
||
<string name="governor_history_loading">Loading…</string>
|
||
<string name="governor_history_empty">No past terms recorded.</string>
|
||
|
||
<!-- ── Falling houses / IDOC (§6.2) ────────────────────────────────── -->
|
||
<string name="houses_empty">No houses are in danger right now.</string>
|
||
<string name="houses_fallback_name">A house</string>
|
||
<string name="houses_idoc_badge">IDOC</string>
|
||
|
||
<!-- ── Push notifications (§11, M7 Part 2) ─────────────────────────── -->
|
||
<string name="menu_notifications">Notifications</string>
|
||
<string name="notifications_title">Notifications</string>
|
||
<string name="notifications_subtitle">Choose what this shard notifies you about. Nothing is sent unless you turn it on.</string>
|
||
<string name="notifications_section_general">General</string>
|
||
<string name="notifications_section_personal">Your game account</string>
|
||
<string name="notifications_requires_link">Link a game account to enable this.</string>
|
||
<string name="notifications_empty">This shard offers no notification streams yet.</string>
|
||
<string name="notifications_unsupported">This shard hasn\'t set up push notifications yet.</string>
|
||
<string name="notifications_saved">Notification settings saved.</string>
|
||
<string name="notifications_all_off">Notifications turned off.</string>
|
||
<string name="notifications_save_error">Couldn\'t save your notification settings. Try again.</string>
|
||
<string name="notifications_relay_error">This shard\'s push relay isn\'t reachable right now.</string>
|
||
|
||
<!-- Notification channels + the ongoing foreground-service notification. -->
|
||
<string name="push_channel_messages">Shard notifications</string>
|
||
<string name="push_channel_messages_desc">Alerts you opted into from this shard.</string>
|
||
<string name="push_channel_service">Background connection</string>
|
||
<string name="push_channel_service_desc">Keeps the connection open to deliver notifications.</string>
|
||
<string name="push_service_title">Notifications active</string>
|
||
<string name="push_service_text">Listening for shard notifications.</string>
|
||
|
||
<!-- Per-stream notification titles (content-free tickle → generic title, §11). -->
|
||
<string name="push_stream_news_post">New post</string>
|
||
<string name="push_stream_server_status">Shard status changed</string>
|
||
<string name="push_stream_idoc_warning">A house is falling (IDOC)</string>
|
||
<string name="push_stream_champ_start">Champion spawn started</string>
|
||
<string name="push_stream_governor_election">New governor elected</string>
|
||
<string name="push_stream_vendor_sale">Your vendor made a sale</string>
|
||
<string name="push_stream_house_idoc">Your house entered IDOC</string>
|
||
<string name="push_stream_account_login">Login to your account</string>
|
||
<string name="push_stream_generic">New notification</string>
|
||
</resources>
|