[{"data":1,"prerenderedAt":417},["ShallowReactive",2],{"navigation_docs":3,"-authentication-google-login":218,"-authentication-google-login-surround":412},[4,20,45,75,95,105,140,168,198],{"title":5,"path":6,"stem":7,"children":8,"page":19},"Introduction","\u002Fintroduction","1.introduction",[9,14],{"title":10,"path":11,"stem":12,"icon":13},"What is GO?","\u002Fintroduction\u002Fwhat-is-go","1.introduction\u002F1.what-is-go","i-lucide-info",{"title":15,"path":16,"stem":17,"icon":18},"Features","\u002Fintroduction\u002Ffeatures","1.introduction\u002F2.features","i-lucide-sparkles",false,{"title":21,"path":22,"stem":23,"children":24,"page":19},"Getting Started","\u002Fgetting-started","2.getting-started",[25,30,35,40],{"title":26,"path":27,"stem":28,"icon":29},"Installation","\u002Fgetting-started\u002Finstallation","2.getting-started\u002F1.installation","i-lucide-download",{"title":31,"path":32,"stem":33,"icon":34},"Configuration","\u002Fgetting-started\u002Fconfiguration","2.getting-started\u002F2.configuration","i-lucide-settings",{"title":36,"path":37,"stem":38,"icon":39},"First Setup","\u002Fgetting-started\u002Ffirst-setup","2.getting-started\u002F3.first-setup","i-lucide-rocket",{"title":41,"path":42,"stem":43,"icon":44},"Updating","\u002Fgetting-started\u002Fupdating","2.getting-started\u002F4.updating","i-lucide-refresh-cw",{"title":46,"icon":19,"path":47,"stem":48,"children":49,"page":19},"User Guide","\u002Fuser-guide","3.user-guide",[50,55,60,65,70],{"title":51,"path":52,"stem":53,"icon":54},"Creating a Short Link","\u002Fuser-guide\u002Fcreating-a-short-link","3.user-guide\u002F1.creating-a-short-link","i-lucide-link",{"title":56,"path":57,"stem":58,"icon":59},"Expiration","\u002Fuser-guide\u002Fexpiration","3.user-guide\u002F2.expiration","i-lucide-clock",{"title":61,"path":62,"stem":63,"icon":64},"Renewing Links","\u002Fuser-guide\u002Frenewing-links","3.user-guide\u002F3.renewing-links","i-lucide-repeat",{"title":66,"path":67,"stem":68,"icon":69},"Dashboard","\u002Fuser-guide\u002Fdashboard","3.user-guide\u002F4.dashboard","i-lucide-layout-dashboard",{"title":71,"path":72,"stem":73,"icon":74},"Analytics","\u002Fuser-guide\u002Fanalytics","3.user-guide\u002F5.analytics","i-lucide-bar-chart-3",{"title":76,"path":77,"stem":78,"children":79,"page":19},"Authentication","\u002Fauthentication","4.authentication",[80,85,90],{"title":81,"path":82,"stem":83,"icon":84},"Email Login","\u002Fauthentication\u002Femail-login","4.authentication\u002F1.email-login","i-lucide-mail",{"title":86,"path":87,"stem":88,"icon":89},"Google Login","\u002Fauthentication\u002Fgoogle-login","4.authentication\u002F2.google-login","i-lucide-globe",{"title":91,"path":92,"stem":93,"icon":94},"Firebase Setup","\u002Fauthentication\u002Ffirebase-setup","4.authentication\u002F3.firebase-setup","i-simple-icons-firebase",{"title":96,"path":97,"stem":98,"children":99,"page":19},"Captcha","\u002Fcaptcha","5.captcha",[100],{"title":101,"path":102,"stem":103,"icon":104},"Cloudflare Turnstile","\u002Fcaptcha\u002Fcloudflare-turnstile","5.captcha\u002F1.cloudflare-turnstile","i-simple-icons-cloudflare",{"title":106,"path":107,"stem":108,"children":109,"page":19},"Administration","\u002Fadministration","6.administration",[110,115,120,125,130,135],{"title":111,"path":112,"stem":113,"icon":114},"Admin Panel","\u002Fadministration\u002Fadmin-panel","6.administration\u002F1.admin-panel","i-lucide-shield",{"title":116,"path":117,"stem":118,"icon":119},"Users","\u002Fadministration\u002Fusers","6.administration\u002F2.users","i-lucide-users",{"title":121,"path":122,"stem":123,"icon":124},"Links","\u002Fadministration\u002Flinks","6.administration\u002F3.links","i-lucide-link-2",{"title":126,"path":127,"stem":128,"icon":129},"Reports","\u002Fadministration\u002Freports","6.administration\u002F4.reports","i-lucide-flag",{"title":131,"path":132,"stem":133,"icon":134},"Bans & Timeouts","\u002Fadministration\u002Fbans-and-timeouts","6.administration\u002F5.bans-and-timeouts","i-lucide-user-x",{"title":136,"path":137,"stem":138,"icon":139},"Audit Logs","\u002Fadministration\u002Faudit-logs","6.administration\u002F6.audit-logs","i-lucide-scroll",{"title":141,"path":142,"stem":143,"children":144,"page":19},"Deployment","\u002Fdeployment","7.deployment",[145,150,155,160,165],{"title":146,"path":147,"stem":148,"icon":149},"VPS Installation","\u002Fdeployment\u002Fvps-installation","7.deployment\u002F1.vps-installation","i-lucide-server",{"title":151,"path":152,"stem":153,"icon":154},"Environment Variables","\u002Fdeployment\u002Fenvironment-variables","7.deployment\u002F2.environment-variables","i-lucide-sliders",{"title":156,"path":157,"stem":158,"icon":159},"Cloudflare Tunnel","\u002Fdeployment\u002Fcloudflare-tunnel","7.deployment\u002F3.cloudflare-tunnel","i-lucide-network",{"title":161,"path":162,"stem":163,"icon":164},"Systemd","\u002Fdeployment\u002Fsystemd","7.deployment\u002F4.systemd","i-lucide-cpu",{"title":41,"path":166,"stem":167,"icon":44},"\u002Fdeployment\u002Fupdating","7.deployment\u002F5.updating",{"title":169,"path":170,"stem":171,"children":172,"page":19},"Developer","\u002Fdeveloper","8.developer",[173,178,183,188,193],{"title":174,"path":175,"stem":176,"icon":177},"Architecture","\u002Fdeveloper\u002Farchitecture","8.developer\u002F1.architecture","i-lucide-box",{"title":179,"path":180,"stem":181,"icon":182},"API Architecture","\u002Fdeveloper\u002Fapi","8.developer\u002F2.api","i-lucide-code-xml",{"title":184,"path":185,"stem":186,"icon":187},"Database","\u002Fdeveloper\u002Fdatabase","8.developer\u002F3.database","i-lucide-database",{"title":189,"path":190,"stem":191,"icon":192},"Development","\u002Fdeveloper\u002Fdevelopment","8.developer\u002F4.development","i-lucide-terminal",{"title":194,"path":195,"stem":196,"icon":197},"Building Releases","\u002Fdeveloper\u002Fbuilding-releases","8.developer\u002F5.building-releases","i-lucide-package-check",{"title":199,"path":200,"stem":201,"children":202,"page":19},"Reference","\u002Freference","9.reference",[203,208,213],{"title":204,"path":205,"stem":206,"icon":207},"Configuration Reference","\u002Freference\u002Fconfiguration","9.reference\u002F1.configuration","i-lucide-file-cog",{"title":209,"path":210,"stem":211,"icon":212},"API Reference","\u002Freference\u002Fapi-reference","9.reference\u002F2.api-reference","i-lucide-webhook",{"title":214,"path":215,"stem":216,"icon":217},"Changelog","\u002Freference\u002Fchangelog","9.reference\u002F3.changelog","i-lucide-history",{"id":219,"title":86,"body":220,"description":403,"extension":404,"links":405,"meta":406,"navigation":407,"path":87,"seo":408,"stem":88,"__hash__":411},"docs\u002F4.authentication\u002F2.google-login.md",{"type":221,"value":222,"toc":395},"minimark",[223,227,236,239,244,255,301,303,307,314,329,334],[224,225,86],"h1",{"id":226},"google-login",[228,229,230,231,235],"p",{},"In addition to traditional email and password credentials, GO Shortener supports ",[232,233,234],"strong",{},"Single Sign-On (SSO) via Google",", allowing users to sign in or register with a single click.",[237,238],"hr",{},[240,241,243],"h2",{"id":242},"authentication-flow","Authentication Flow",[245,246,251],"pre",{"className":247,"code":249,"language":250},[248],"language-text","+----------+              +------------+              +-----------------+\n| Browser  | ------------ |  Firebase  | ------------ |  Google OAuth   |\n+----------+              +------------+              +-----------------+\n     |                          |                              |\n     | 1. Click \"Sign in\"       |                              |\n     |------------------------> |                              |\n     |                          | 2. Perform OAuth Consent     |\n     |                          |----------------------------> |\n     |                          | 3. ID Token Returned         |\n     |                          |\u003C---------------------------- |\n     | 4. Receive Firebase JWT  |                              |\n     |\u003C-------------------------|                              |\n     |                                                         |\n     | 5. POST \u002Fapi\u002Fauth\u002Fgoogle { idToken }                    |\n     |-------------------------------------------------------->|\n     |                                                         |\n     | 6. Validate Token & Issue `go_session` Cookie           |\n     |\u003C--------------------------------------------------------|\n","text",[252,253,249],"code",{"__ignoreMap":254},"",[256,257,258,269,275,281,291],"ol",{},[259,260,261,264,265,268],"li",{},[232,262,263],{},"Client-Side Trigger",": The user clicks ",[232,266,267],{},"Continue with Google"," on the login or registration modal.",[259,270,271,274],{},[232,272,273],{},"Google OAuth Popup",": Firebase Web SDK manages the OAuth popup flow and Google account consent.",[259,276,277,280],{},[232,278,279],{},"ID Token Generation",": Upon authorization, Firebase issues a signed OpenID Connect (OIDC) JWT to the browser.",[259,282,283,286,287,290],{},[232,284,285],{},"Backend Verification",": The browser submits the JWT to ",[252,288,289],{},"POST \u002Fapi\u002Fauth\u002Fgoogle",". The GO backend cryptographically verifies the token's signature, issuer, and audience against Google's public certificates.",[259,292,293,296,297,300],{},[232,294,295],{},"Session Established",": The backend issues the standard ",[252,298,299],{},"go_session"," cookie, seamlessly authenticating the user.",[237,302],{},[240,304,306],{"id":305},"automatic-account-linking","Automatic Account Linking",[228,308,309,310,313],{},"A key design feature in GO Shortener is ",[232,311,312],{},"Safe Account Linking",":",[315,316,317,318,321,322,324,325,328],"tip",{},"If a user initially registered an account using an email and password (e.g., ",[252,319,320],{},"alice@example.com",") and subsequently clicks ",[232,323,267],{}," with that same Google account, GO ",[232,326,327],{},"links the credentials automatically"," rather than failing or creating a duplicate user row.",[330,331,333],"h3",{"id":332},"linking-logic","Linking Logic:",[256,335,336,339,346,370],{},[259,337,338],{},"The backend extracts the verified email address and Firebase UID from the validated Google token.",[259,340,341,342,345],{},"It queries the ",[252,343,344],{},"users"," table for an existing record matching that email address.",[259,347,348,349],{},"If found:\n",[350,351,352,358,364],"ul",{},[259,353,354,355],{},"Sets ",[252,356,357],{},"firebase_uid = token.UID",[259,359,354,360,363],{},[252,361,362],{},"auth_provider = \"google\""," (or hybrid)",[259,365,366,367],{},"Updates ",[252,368,369],{},"last_login_at = CURRENT_TIMESTAMP",[259,371,372,373],{},"If not found:\n",[350,374,375,392],{},[259,376,377,378,381,382,381,385,388,389,391],{},"Creates a new user row with ",[252,379,380],{},"email",", ",[252,383,384],{},"first_name",[252,386,387],{},"last_name",", and ",[252,390,362],{},".",[259,393,394],{},"The user immediately inherits the normal registered user quota (100 links\u002Fmonth).",{"title":254,"searchDepth":396,"depth":396,"links":397},2,[398,399],{"id":242,"depth":396,"text":243},{"id":305,"depth":396,"text":306,"children":400},[401],{"id":332,"depth":402,"text":333},3,"Single Sign-On using Google OAuth with automatic account linking.","md",null,{},{"icon":89},{"title":409,"description":410},"Google Login & Account Linking - GO Shortener","How Google OAuth authentication works in GO Shortener with automatic account linking and Firebase verification.","D_gtrVSWWaE-tHgxOyCYvq3GEW3xD5yAq-YEPh8Kwww",[413,415],{"title":81,"path":82,"stem":83,"description":414,"icon":84,"children":-1},"Native email and password authentication with bcrypt security.",{"title":91,"path":92,"stem":93,"description":416,"icon":94,"children":-1},"Step-by-step instructions for configuring Firebase Authentication and Google OAuth.",1788462426832]