[{"data":1,"prerenderedAt":1942},["ShallowReactive",2],{"navigation_docs":3,"-core-concepts-sessions":265,"-core-concepts-sessions-surround":1937},[4,35,49,89,117,164,193,235,253,257,261],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting Started",false,"/getting-started","1.getting-started",[10,15,20,25,30],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","/getting-started/introduction","1.getting-started/2.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Installation","/getting-started/installation","1.getting-started/3.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quick Start","/getting-started/quick-start","1.getting-started/4.quick-start","i-lucide-rocket",{"title":26,"path":27,"stem":28,"icon":29},"Configuration","/getting-started/configuration","1.getting-started/5.configuration","i-lucide-sliders-horizontal",{"title":31,"path":32,"stem":33,"icon":34},"First Auth","/getting-started/first-auth","1.getting-started/6.first-auth","i-lucide-key-round",{"title":36,"path":37,"stem":38,"children":39,"page":6},"Migration","/migration","10.migration",[40,45],{"title":41,"path":42,"stem":43,"icon":44},"Migration depuis Firebase Auth","/migration/from-firebase","10.migration/1.from-firebase","i-lucide-arrow-right-left",{"title":46,"path":47,"stem":48,"icon":44},"Migration depuis Supabase Auth","/migration/from-supabase","10.migration/2.from-supabase",{"title":50,"path":51,"stem":52,"children":53,"page":6},"Core Concepts","/core-concepts","2.core-concepts",[54,59,64,69,74,79,84],{"title":55,"path":56,"stem":57,"icon":58},"Architecture","/core-concepts/architecture","2.core-concepts/1.architecture","i-lucide-layers",{"title":60,"path":61,"stem":62,"icon":63},"Providers","/core-concepts/providers","2.core-concepts/2.providers","i-lucide-plug",{"title":65,"path":66,"stem":67,"icon":68},"Sessions","/core-concepts/sessions","2.core-concepts/3.sessions","i-lucide-timer",{"title":70,"path":71,"stem":72,"icon":73},"Storage","/core-concepts/storage","2.core-concepts/4.storage","i-lucide-database",{"title":75,"path":76,"stem":77,"icon":78},"Reactivity","/core-concepts/reactivity","2.core-concepts/5.reactivity","i-lucide-activity",{"title":80,"path":81,"stem":82,"icon":83},"Callbacks","/core-concepts/callbacks","2.core-concepts/6.callbacks","i-lucide-shield-check",{"title":85,"path":86,"stem":87,"icon":88},"Events","/core-concepts/events","2.core-concepts/7.events","i-lucide-radio",{"title":60,"path":90,"stem":91,"children":92,"page":6},"/providers","3.providers",[93,97,101,105,109,113],{"title":94,"path":95,"stem":96},"Credentials Provider","/providers/credentials","3.providers/1.credentials",{"title":98,"path":99,"stem":100},"OAuth2 Provider","/providers/oauth2","3.providers/2.oauth2",{"title":102,"path":103,"stem":104},"Google Provider","/providers/google","3.providers/3.google",{"title":106,"path":107,"stem":108},"GitHub Provider","/providers/github","3.providers/4.github",{"title":110,"path":111,"stem":112},"Apple Provider","/providers/apple","3.providers/5.apple",{"title":114,"path":115,"stem":116},"Proxy OAuth Provider","/providers/proxy-oauth","3.providers/6.proxy-oauth",{"title":118,"path":119,"stem":120,"children":121,"page":6},"Guides","/guides","4.guides",[122,126,131,136,141,146,151,155,159],{"title":123,"path":124,"stem":125},"Email / Password Auth","/guides/email-auth","4.guides/1.email-auth",{"title":127,"path":128,"stem":129,"icon":130},"Custom OAuth2 Flow","/guides/oauth2-flow","4.guides/2.oauth2-flow","i-lucide-workflow",{"title":132,"path":133,"stem":134,"icon":135},"Deep Links & OAuth2 Callbacks","/guides/deep-links","4.guides/3.deep-links","i-lucide-link",{"title":137,"path":138,"stem":139,"icon":140},"Token Refresh","/guides/token-refresh","4.guides/4.token-refresh","i-lucide-refresh-cw",{"title":142,"path":143,"stem":144,"icon":145},"Multi-Account","/guides/multi-account","4.guides/5.multi-account","i-lucide-users",{"title":147,"path":148,"stem":149,"icon":150},"Route Protection","/guides/route-protection","4.guides/6.route-protection","i-lucide-lock",{"title":152,"path":153,"stem":154,"icon":63},"Custom Provider","/guides/custom-provider","4.guides/7.custom-provider",{"title":156,"path":157,"stem":158,"icon":73},"Custom Storage","/guides/custom-storage","4.guides/8.custom-storage",{"title":160,"path":161,"stem":162,"icon":163},"Testing","/guides/testing","4.guides/9.testing","i-lucide-flask-conical",{"title":165,"path":166,"stem":167,"children":168,"page":6},"Flutter","/flutter","5.flutter",[169,173,178,183,188],{"title":170,"path":171,"stem":172},"Flutter Setup","/flutter/setup","5.flutter/1.setup",{"title":174,"path":175,"stem":176,"icon":177},"Secure Storage","/flutter/secure-storage","5.flutter/2.secure-storage","i-lucide-vault",{"title":179,"path":180,"stem":181,"icon":182},"Widgets","/flutter/widgets","5.flutter/3.widgets","i-lucide-layout",{"title":184,"path":185,"stem":186,"icon":187},"Router Guard","/flutter/router-guard","5.flutter/4.router-guard","i-lucide-signpost",{"title":189,"path":190,"stem":191,"icon":192},"App Binding","/flutter/app-binding","5.flutter/5.app-binding","i-lucide-cpu",{"title":194,"path":195,"stem":196,"children":197,"page":6},"API Reference","/api-reference","6.api-reference",[198,202,206,211,216,221,225,230],{"title":199,"path":200,"stem":201},"AuthyraClient","/api-reference/authyra-client","6.api-reference/1.authyra-client",{"title":203,"path":204,"stem":205},"AuthyraInstance","/api-reference/authyra-instance","6.api-reference/2.authyra-instance",{"title":207,"path":208,"stem":209,"icon":210},"AccountManager","/api-reference/account-manager","6.api-reference/3.account-manager","i-lucide-users-round",{"title":212,"path":213,"stem":214,"icon":215},"AuthProvider","/api-reference/auth-provider","6.api-reference/4.auth-provider","i-lucide-plug-zap",{"title":217,"path":218,"stem":219,"icon":220},"AuthStorage","/api-reference/auth-storage","6.api-reference/5.auth-storage","i-lucide-hard-drive",{"title":222,"path":223,"stem":224,"icon":68},"AuthSession","/api-reference/auth-session","6.api-reference/6.auth-session",{"title":226,"path":227,"stem":228,"icon":229},"AuthState","/api-reference/auth-state","6.api-reference/7.auth-state","i-lucide-toggle-right",{"title":231,"path":232,"stem":233,"icon":234},"Exceptions","/api-reference/auth-exceptions","6.api-reference/8.auth-exceptions","i-lucide-triangle-alert",{"title":236,"path":237,"stem":238,"children":239,"page":6},"Examples","/examples","7.examples",[240,244,249],{"title":241,"path":242,"stem":243},"Flutter App Example","/examples/flutter-app","7.examples/1.flutter-app",{"title":245,"path":246,"stem":247,"icon":248},"Dart Backend","/examples/dart-backend","7.examples/2.dart-backend","i-lucide-server",{"title":250,"path":251,"stem":252,"icon":163},"Testing Setup","/examples/testing-setup","7.examples/3.testing-setup",{"title":254,"path":255,"stem":256},"Troubleshooting","/troubleshooting","8.troubleshooting",{"title":258,"path":259,"stem":260},"FAQ","/faq","9.faq",{"title":262,"path":263,"stem":264},"Changelog","/changelog","changelog",{"id":266,"title":65,"body":267,"description":1928,"extension":1929,"links":1930,"meta":1931,"navigation":1932,"path":66,"seo":1933,"stem":67,"__hash__":1936},"docs/2.core-concepts/3.sessions.md",{"type":268,"value":269,"toc":1911},"minimark",[270,277,280,285,438,567,569,573,581,583,587,594,610,632,638,682,691,792,798,832,841,890,896,910,921,988,990,994,997,1028,1116,1129,1131,1135,1152,1158,1160,1164,1348,1350,1354,1362,1568,1577,1579,1583,1595,1758,1765,1767,1772,1778,1872,1874,1878,1907],[271,272,273,276],"p",{},[274,275,222],"code",{}," is the core data object that represents an authenticated user's active session. It carries the user's identity, tokens, expiry metadata, and the provider that created it.",[278,279],"hr",{},[281,282,284],"h2",{"id":283},"fields","Fields",[286,287,292],"pre",{"className":288,"code":289,"language":290,"meta":291,"style":291},"language-dart shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","class AuthSession {\n  final String    providerId;       // 'google', 'email', etc.\n  final AuthUser  user;\n  final String?   accessToken;\n  final String?   refreshToken;\n  final DateTime? expiresAt;\n  final List\u003CString> linkedProviders;\n  final DateTime  createdAt;\n  final DateTime  lastUsedAt;\n}\n","dart","",[274,293,294,311,331,345,360,374,389,408,420,432],{"__ignoreMap":291},[295,296,299,303,307],"span",{"class":297,"line":298},"line",1,[295,300,302],{"class":301},"sMK4o","class",[295,304,306],{"class":305},"sBMFI"," AuthSession",[295,308,310],{"class":309},"sTEyZ"," {\n",[295,312,314,318,321,324,327],{"class":297,"line":313},2,[295,315,317],{"class":316},"spNyl","  final",[295,319,320],{"class":305}," String",[295,322,323],{"class":309},"    providerId",[295,325,326],{"class":301},";",[295,328,330],{"class":329},"sHwdD","       // 'google', 'email', etc.\n",[295,332,334,336,339,342],{"class":297,"line":333},3,[295,335,317],{"class":316},[295,337,338],{"class":305}," AuthUser",[295,340,341],{"class":309},"  user",[295,343,344],{"class":301},";\n",[295,346,348,350,352,355,358],{"class":297,"line":347},4,[295,349,317],{"class":316},[295,351,320],{"class":305},[295,353,354],{"class":301},"?",[295,356,357],{"class":309},"   accessToken",[295,359,344],{"class":301},[295,361,363,365,367,369,372],{"class":297,"line":362},5,[295,364,317],{"class":316},[295,366,320],{"class":305},[295,368,354],{"class":301},[295,370,371],{"class":309},"   refreshToken",[295,373,344],{"class":301},[295,375,377,379,382,384,387],{"class":297,"line":376},6,[295,378,317],{"class":316},[295,380,381],{"class":305}," DateTime",[295,383,354],{"class":301},[295,385,386],{"class":309}," expiresAt",[295,388,344],{"class":301},[295,390,392,394,397,400,403,406],{"class":297,"line":391},7,[295,393,317],{"class":316},[295,395,396],{"class":305}," List",[295,398,399],{"class":309},"\u003C",[295,401,402],{"class":305},"String",[295,404,405],{"class":309},"> linkedProviders",[295,407,344],{"class":301},[295,409,411,413,415,418],{"class":297,"line":410},8,[295,412,317],{"class":316},[295,414,381],{"class":305},[295,416,417],{"class":309},"  createdAt",[295,419,344],{"class":301},[295,421,423,425,427,430],{"class":297,"line":422},9,[295,424,317],{"class":316},[295,426,381],{"class":305},[295,428,429],{"class":309},"  lastUsedAt",[295,431,344],{"class":301},[295,433,435],{"class":297,"line":434},10,[295,436,437],{"class":309},"}\n",[439,440,441,454],"table",{},[442,443,444],"thead",{},[445,446,447,451],"tr",{},[448,449,450],"th",{},"Field",[448,452,453],{},"Description",[455,456,457,468,494,508,521,537,547,557],"tbody",{},[445,458,459,465],{},[460,461,462],"td",{},[274,463,464],{},"providerId",[460,466,467],{},"Slug of the provider that created this session",[445,469,470,475],{},[460,471,472],{},[274,473,474],{},"user",[460,476,477,478,481,482,481,485,481,488,481,491],{},"Identity profile — ",[274,479,480],{},"id",", ",[274,483,484],{},"email",[274,486,487],{},"name",[274,489,490],{},"avatarUrl",[274,492,493],{},"metadata",[445,495,496,501],{},[460,497,498],{},[274,499,500],{},"accessToken",[460,502,503,504,507],{},"Short-lived token for API requests. ",[274,505,506],{},"null"," for cookie-session flows",[445,509,510,515],{},[460,511,512],{},[274,513,514],{},"refreshToken",[460,516,517,518,520],{},"Long-lived token for silent renewal. ",[274,519,506],{}," if not returned by the provider",[445,522,523,528],{},[460,524,525],{},[274,526,527],{},"expiresAt",[460,529,530,531,533,534,536],{},"UTC expiry of ",[274,532,500],{},". ",[274,535,506],{}," = no known expiry",[445,538,539,544],{},[460,540,541],{},[274,542,543],{},"linkedProviders",[460,545,546],{},"All providers linked to this account (for multi-provider users)",[445,548,549,554],{},[460,550,551],{},[274,552,553],{},"createdAt",[460,555,556],{},"When this session was first created",[445,558,559,564],{},[460,560,561],{},[274,562,563],{},"lastUsedAt",[460,565,566],{},"Timestamp of the most recent activity — used for recency sorting",[278,568],{},[281,570,572],{"id":571},"lifecycle","Lifecycle",[286,574,579],{"className":575,"code":577,"language":578,"meta":291},[576],"language-text","signIn()\n    └─ provider.signIn() returns AuthSignInResult\n           └─ AuthyraClient builds AuthSession\n                  └─ SessionManager.saveSession(session)\n                         └─ persisted to AuthStorage\n                                └─ authStateChanges emits AuthState.authenticated\n\n        ↓  (token approaching expiry)\n\nsession.shouldRefresh → true\n    └─ provider.refreshToken(session.refreshToken)\n           └─ session.refreshed(newAccessToken, newExpiresAt)\n                  └─ SessionManager.updateSession()\n                         └─ authStateChanges emits refreshed state\n\n        ↓  (sign-out)\n\nsignOut()\n    └─ provider.signOut()  [if supportsSignOut]\n           └─ SessionManager.clearActiveSession()\n                  └─ storage cleared\n                         └─ authStateChanges emits AuthState.unauthenticated\n","text",[274,580,577],{"__ignoreMap":291},[278,582],{},[281,584,586],{"id":585},"expiry-helpers","Expiry helpers",[588,589,591],"h3",{"id":590},"isexpired",[274,592,593],{},"isExpired",[286,595,597],{"className":288,"code":596,"language":290,"meta":291,"style":291},"bool get isExpired\n",[274,598,599],{"__ignoreMap":291},[295,600,601,604,607],{"class":297,"line":298},[295,602,603],{"class":305},"bool",[295,605,606],{"class":301}," get",[295,608,609],{"class":309}," isExpired\n",[271,611,612,615,616,619,620,622,623,615,626,628,629,631],{},[274,613,614],{},"true"," when ",[274,617,618],{},"DateTime.now()"," is past ",[274,621,527],{},". Returns ",[274,624,625],{},"false",[274,627,527],{}," is ",[274,630,506],{},".",[588,633,635],{"id":634},"isexpiringsoon",[274,636,637],{},"isExpiringSoon",[286,639,641],{"className":288,"code":640,"language":290,"meta":291,"style":291},"bool isExpiringSoon([Duration threshold = const Duration(minutes: 5)])\n",[274,642,643],{"__ignoreMap":291},[295,644,645,647,651,654,657,660,663,666,669,672,675,679],{"class":297,"line":298},[295,646,603],{"class":305},[295,648,650],{"class":649},"s2Zo4"," isExpiringSoon",[295,652,653],{"class":309},"([",[295,655,656],{"class":305},"Duration",[295,658,659],{"class":309}," threshold ",[295,661,662],{"class":301},"=",[295,664,665],{"class":316}," const",[295,667,668],{"class":305}," Duration",[295,670,671],{"class":309},"(minutes",[295,673,674],{"class":301},":",[295,676,678],{"class":677},"sbssI"," 5",[295,680,681],{"class":309},")])\n",[271,683,684,686,687,690],{},[274,685,614],{}," when the token expires within ",[274,688,689],{},"threshold",". Use for manual pre-emptive refresh:",[286,692,694],{"className":288,"code":693,"language":290,"meta":291,"style":291},"final session = await Authyra.instance.getSession();\nif (session?.isExpiringSoon(const Duration(minutes: 10)) ?? false) {\n  await Authyra.instance.refreshSession();\n}\n",[274,695,696,728,768,788],{"__ignoreMap":291},[295,697,698,701,704,706,710,713,715,718,720,723,726],{"class":297,"line":298},[295,699,700],{"class":316},"final",[295,702,703],{"class":309}," session ",[295,705,662],{"class":301},[295,707,709],{"class":708},"s7zQu"," await",[295,711,712],{"class":305}," Authyra",[295,714,631],{"class":301},[295,716,717],{"class":309},"instance",[295,719,631],{"class":301},[295,721,722],{"class":649},"getSession",[295,724,725],{"class":309},"()",[295,727,344],{"class":301},[295,729,730,733,736,739,741,744,747,749,751,753,756,759,762,765],{"class":297,"line":313},[295,731,732],{"class":708},"if",[295,734,735],{"class":309}," (session",[295,737,738],{"class":301},"?.",[295,740,637],{"class":649},[295,742,743],{"class":309},"(",[295,745,746],{"class":316},"const",[295,748,668],{"class":305},[295,750,671],{"class":309},[295,752,674],{"class":301},[295,754,755],{"class":677}," 10",[295,757,758],{"class":309},")) ",[295,760,761],{"class":301},"??",[295,763,764],{"class":301}," false",[295,766,767],{"class":309},") {\n",[295,769,770,773,775,777,779,781,784,786],{"class":297,"line":333},[295,771,772],{"class":708},"  await",[295,774,712],{"class":305},[295,776,631],{"class":301},[295,778,717],{"class":309},[295,780,631],{"class":301},[295,782,783],{"class":649},"refreshSession",[295,785,725],{"class":309},[295,787,344],{"class":301},[295,789,790],{"class":297,"line":347},[295,791,437],{"class":309},[588,793,795],{"id":794},"shouldrefresh",[274,796,797],{},"shouldRefresh",[286,799,801],{"className":288,"code":800,"language":290,"meta":291,"style":291},"bool shouldRefresh({Duration threshold = const Duration(minutes: 5)})\n",[274,802,803],{"__ignoreMap":291},[295,804,805,807,810,813,815,817,819,821,823,825,827,829],{"class":297,"line":298},[295,806,603],{"class":305},[295,808,809],{"class":649}," shouldRefresh",[295,811,812],{"class":309},"({",[295,814,656],{"class":305},[295,816,659],{"class":309},[295,818,662],{"class":301},[295,820,665],{"class":316},[295,822,668],{"class":305},[295,824,671],{"class":309},[295,826,674],{"class":301},[295,828,678],{"class":677},[295,830,831],{"class":309},")})\n",[271,833,834,835,837,838,840],{},"Semantically identical to ",[274,836,637],{}," but accepts a named parameter — used internally by ",[274,839,199],{},"'s auto-refresh scheduler:",[286,842,844],{"className":288,"code":843,"language":290,"meta":291,"style":291},"if (session.shouldRefresh(threshold: config.refreshThreshold)) {\n  await client.refresh(session);\n}\n",[274,845,846,869,886],{"__ignoreMap":291},[295,847,848,850,852,854,856,859,861,864,866],{"class":297,"line":298},[295,849,732],{"class":708},[295,851,735],{"class":309},[295,853,631],{"class":301},[295,855,797],{"class":649},[295,857,858],{"class":309},"(threshold",[295,860,674],{"class":301},[295,862,863],{"class":309}," config",[295,865,631],{"class":301},[295,867,868],{"class":309},"refreshThreshold)) {\n",[295,870,871,873,876,878,881,884],{"class":297,"line":313},[295,872,772],{"class":708},[295,874,875],{"class":309}," client",[295,877,631],{"class":301},[295,879,880],{"class":649},"refresh",[295,882,883],{"class":309},"(session)",[295,885,344],{"class":301},[295,887,888],{"class":297,"line":333},[295,889,437],{"class":309},[588,891,893],{"id":892},"timeuntilexpiration",[274,894,895],{},"timeUntilExpiration",[286,897,899],{"className":288,"code":898,"language":290,"meta":291,"style":291},"Duration get timeUntilExpiration\n",[274,900,901],{"__ignoreMap":291},[295,902,903,905,907],{"class":297,"line":298},[295,904,656],{"class":305},[295,906,606],{"class":301},[295,908,909],{"class":309}," timeUntilExpiration\n",[271,911,912,913,916,917,628,919,631],{},"Remaining time until the access token expires. Returns ",[274,914,915],{},"Duration.zero"," when already expired or when ",[274,918,527],{},[274,920,506],{},[286,922,924],{"className":288,"code":923,"language":290,"meta":291,"style":291},"final remaining = session?.timeUntilExpiration ?? Duration.zero;\nprint('Token valid for ${remaining.inMinutes} more minutes');\n",[274,925,926,954],{"__ignoreMap":291},[295,927,928,930,933,935,938,940,943,945,947,949,952],{"class":297,"line":298},[295,929,700],{"class":316},[295,931,932],{"class":309}," remaining ",[295,934,662],{"class":301},[295,936,937],{"class":309}," session",[295,939,738],{"class":301},[295,941,942],{"class":309},"timeUntilExpiration ",[295,944,761],{"class":301},[295,946,668],{"class":305},[295,948,631],{"class":301},[295,950,951],{"class":309},"zero",[295,953,344],{"class":301},[295,955,956,959,961,965,968,972,974,977,980,983,986],{"class":297,"line":313},[295,957,958],{"class":649},"print",[295,960,743],{"class":309},[295,962,964],{"class":963},"sfazB","'Token valid for ",[295,966,967],{"class":309},"${",[295,969,971],{"class":970},"sHdIc","remaining",[295,973,631],{"class":309},[295,975,976],{"class":970},"inMinutes",[295,978,979],{"class":309},"}",[295,981,982],{"class":963}," more minutes'",[295,984,985],{"class":309},")",[295,987,344],{"class":301},[278,989],{},[281,991,993],{"id":992},"token-refresh","Token refresh",[271,995,996],{},"When the session should be refreshed:",[998,999,1000,1009,1015,1021],"ol",{},[1001,1002,1003,1005,1006,631],"li",{},[274,1004,199],{}," calls ",[274,1007,1008],{},"provider.refreshToken(session.refreshToken)",[1001,1010,1011,1012,631],{},"The provider returns an ",[274,1013,1014],{},"AuthTokenResult",[1001,1016,1017,1018,631],{},"The session is updated via ",[274,1019,1020],{},"session.refreshed(...)",[1001,1022,1023,1024,1027],{},"The new session is persisted and ",[274,1025,1026],{},"authStateChanges"," emits the updated state.",[286,1029,1031],{"className":288,"code":1030,"language":290,"meta":291,"style":291},"// The refreshed() helper produces an updated AuthSession:\nfinal renewed = session.refreshed(\n  newAccessToken:  result.accessToken,\n  newRefreshToken: result.refreshToken,  // null = keep existing\n  newExpiresAt:    result.expiresAt,\n);\n",[274,1032,1033,1038,1057,1074,1094,1110],{"__ignoreMap":291},[295,1034,1035],{"class":297,"line":298},[295,1036,1037],{"class":329},"// The refreshed() helper produces an updated AuthSession:\n",[295,1039,1040,1042,1045,1047,1049,1051,1054],{"class":297,"line":313},[295,1041,700],{"class":316},[295,1043,1044],{"class":309}," renewed ",[295,1046,662],{"class":301},[295,1048,937],{"class":309},[295,1050,631],{"class":301},[295,1052,1053],{"class":649},"refreshed",[295,1055,1056],{"class":309},"(\n",[295,1058,1059,1062,1064,1067,1069,1071],{"class":297,"line":333},[295,1060,1061],{"class":309},"  newAccessToken",[295,1063,674],{"class":301},[295,1065,1066],{"class":309},"  result",[295,1068,631],{"class":301},[295,1070,500],{"class":309},[295,1072,1073],{"class":301},",\n",[295,1075,1076,1079,1081,1084,1086,1088,1091],{"class":297,"line":347},[295,1077,1078],{"class":309},"  newRefreshToken",[295,1080,674],{"class":301},[295,1082,1083],{"class":309}," result",[295,1085,631],{"class":301},[295,1087,514],{"class":309},[295,1089,1090],{"class":301},",",[295,1092,1093],{"class":329},"  // null = keep existing\n",[295,1095,1096,1099,1101,1104,1106,1108],{"class":297,"line":362},[295,1097,1098],{"class":309},"  newExpiresAt",[295,1100,674],{"class":301},[295,1102,1103],{"class":309},"    result",[295,1105,631],{"class":301},[295,1107,527],{"class":309},[295,1109,1073],{"class":301},[295,1111,1112,1114],{"class":297,"line":376},[295,1113,985],{"class":309},[295,1115,344],{"class":301},[271,1117,1118,1119,1121,1122,1124,1125,1128],{},"When ",[274,1120,514],{}," returns ",[274,1123,506],{}," (expired or revoked), the session is cleared and ",[274,1126,1127],{},"AuthState.unauthenticated()"," is emitted.",[278,1130],{},[281,1132,1134],{"id":1133},"canrefresh","canRefresh",[286,1136,1138],{"className":288,"code":1137,"language":290,"meta":291,"style":291},"bool get canRefresh  // refreshToken != null && refreshToken.isNotEmpty\n",[274,1139,1140],{"__ignoreMap":291},[295,1141,1142,1144,1146,1149],{"class":297,"line":298},[295,1143,603],{"class":305},[295,1145,606],{"class":301},[295,1147,1148],{"class":309}," canRefresh  ",[295,1150,1151],{"class":329},"// refreshToken != null && refreshToken.isNotEmpty\n",[271,1153,1154,1155,631],{},"Quick check before attempting a refresh. Providers that don't return a refresh token (e.g., cookie-session flows) will have ",[274,1156,1157],{},"canRefresh: false",[278,1159],{},[281,1161,1163],{"id":1162},"reading-the-session","Reading the session",[286,1165,1167],{"className":288,"code":1166,"language":290,"meta":291,"style":291},"// Async — full session object\nfinal session = await Authyra.instance.getSession();\nprint('Provider: ${session?.providerId}');\nprint('Expires: ${session?.expiresAt}');\nprint('Can refresh: ${session?.canRefresh}');\n\n// Async — just the access token (triggers auto-refresh if needed)\nfinal token = await Authyra.instance.getAccessToken();\nmyHttpClient.options.headers['Authorization'] = 'Bearer $token';\n",[274,1168,1169,1174,1198,1225,1250,1275,1281,1286,1312],{"__ignoreMap":291},[295,1170,1171],{"class":297,"line":298},[295,1172,1173],{"class":329},"// Async — full session object\n",[295,1175,1176,1178,1180,1182,1184,1186,1188,1190,1192,1194,1196],{"class":297,"line":313},[295,1177,700],{"class":316},[295,1179,703],{"class":309},[295,1181,662],{"class":301},[295,1183,709],{"class":708},[295,1185,712],{"class":305},[295,1187,631],{"class":301},[295,1189,717],{"class":309},[295,1191,631],{"class":301},[295,1193,722],{"class":649},[295,1195,725],{"class":309},[295,1197,344],{"class":301},[295,1199,1200,1202,1204,1207,1209,1212,1214,1216,1218,1221,1223],{"class":297,"line":333},[295,1201,958],{"class":649},[295,1203,743],{"class":309},[295,1205,1206],{"class":963},"'Provider: ",[295,1208,967],{"class":309},[295,1210,1211],{"class":970},"session",[295,1213,738],{"class":309},[295,1215,464],{"class":970},[295,1217,979],{"class":309},[295,1219,1220],{"class":963},"'",[295,1222,985],{"class":309},[295,1224,344],{"class":301},[295,1226,1227,1229,1231,1234,1236,1238,1240,1242,1244,1246,1248],{"class":297,"line":347},[295,1228,958],{"class":649},[295,1230,743],{"class":309},[295,1232,1233],{"class":963},"'Expires: ",[295,1235,967],{"class":309},[295,1237,1211],{"class":970},[295,1239,738],{"class":309},[295,1241,527],{"class":970},[295,1243,979],{"class":309},[295,1245,1220],{"class":963},[295,1247,985],{"class":309},[295,1249,344],{"class":301},[295,1251,1252,1254,1256,1259,1261,1263,1265,1267,1269,1271,1273],{"class":297,"line":362},[295,1253,958],{"class":649},[295,1255,743],{"class":309},[295,1257,1258],{"class":963},"'Can refresh: ",[295,1260,967],{"class":309},[295,1262,1211],{"class":970},[295,1264,738],{"class":309},[295,1266,1134],{"class":970},[295,1268,979],{"class":309},[295,1270,1220],{"class":963},[295,1272,985],{"class":309},[295,1274,344],{"class":301},[295,1276,1277],{"class":297,"line":376},[295,1278,1280],{"emptyLinePlaceholder":1279},true,"\n",[295,1282,1283],{"class":297,"line":391},[295,1284,1285],{"class":329},"// Async — just the access token (triggers auto-refresh if needed)\n",[295,1287,1288,1290,1293,1295,1297,1299,1301,1303,1305,1308,1310],{"class":297,"line":410},[295,1289,700],{"class":316},[295,1291,1292],{"class":309}," token ",[295,1294,662],{"class":301},[295,1296,709],{"class":708},[295,1298,712],{"class":305},[295,1300,631],{"class":301},[295,1302,717],{"class":309},[295,1304,631],{"class":301},[295,1306,1307],{"class":649},"getAccessToken",[295,1309,725],{"class":309},[295,1311,344],{"class":301},[295,1313,1314,1317,1319,1322,1324,1327,1330,1333,1335,1338,1341,1344,1346],{"class":297,"line":422},[295,1315,1316],{"class":309},"myHttpClient",[295,1318,631],{"class":301},[295,1320,1321],{"class":309},"options",[295,1323,631],{"class":301},[295,1325,1326],{"class":309},"headers[",[295,1328,1329],{"class":963},"'Authorization'",[295,1331,1332],{"class":309},"] ",[295,1334,662],{"class":301},[295,1336,1337],{"class":963}," 'Bearer ",[295,1339,1340],{"class":309},"$",[295,1342,1343],{"class":970},"token",[295,1345,1220],{"class":963},[295,1347,344],{"class":301},[278,1349],{},[281,1351,1353],{"id":1352},"serialisation","Serialisation",[271,1355,1356,1358,1359,1361],{},[274,1357,222],{}," is serialised to/from JSON for persistence in ",[274,1360,217],{},". Timestamps are encoded as ISO 8601 strings:",[286,1363,1367],{"className":1364,"code":1365,"language":1366,"meta":291,"style":291},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"providerId\":     \"google\",\n  \"user\":           { \"id\": \"123\", \"email\": \"alice@example.com\" },\n  \"accessToken\":    \"ya29.xxx\",\n  \"refreshToken\":   \"1//yyy\",\n  \"expiresAt\":      \"2026-03-01T12:00:00.000Z\",\n  \"linkedProviders\": [\"google\"],\n  \"createdAt\":      \"2026-02-01T08:00:00.000Z\",\n  \"lastUsedAt\":     \"2026-02-23T10:30:00.000Z\"\n}\n","json",[274,1368,1369,1374,1396,1445,1465,1485,1505,1527,1546,1564],{"__ignoreMap":291},[295,1370,1371],{"class":297,"line":298},[295,1372,1373],{"class":301},"{\n",[295,1375,1376,1379,1381,1384,1386,1389,1392,1394],{"class":297,"line":313},[295,1377,1378],{"class":301},"  \"",[295,1380,464],{"class":316},[295,1382,1383],{"class":301},"\"",[295,1385,674],{"class":301},[295,1387,1388],{"class":301},"     \"",[295,1390,1391],{"class":963},"google",[295,1393,1383],{"class":301},[295,1395,1073],{"class":301},[295,1397,1398,1400,1402,1404,1406,1409,1412,1414,1416,1418,1420,1423,1425,1427,1429,1431,1433,1435,1437,1440,1442],{"class":297,"line":333},[295,1399,1378],{"class":301},[295,1401,474],{"class":316},[295,1403,1383],{"class":301},[295,1405,674],{"class":301},[295,1407,1408],{"class":301},"           {",[295,1410,1411],{"class":301}," \"",[295,1413,480],{"class":305},[295,1415,1383],{"class":301},[295,1417,674],{"class":301},[295,1419,1411],{"class":301},[295,1421,1422],{"class":963},"123",[295,1424,1383],{"class":301},[295,1426,1090],{"class":301},[295,1428,1411],{"class":301},[295,1430,484],{"class":305},[295,1432,1383],{"class":301},[295,1434,674],{"class":301},[295,1436,1411],{"class":301},[295,1438,1439],{"class":963},"alice@example.com",[295,1441,1383],{"class":301},[295,1443,1444],{"class":301}," },\n",[295,1446,1447,1449,1451,1453,1455,1458,1461,1463],{"class":297,"line":347},[295,1448,1378],{"class":301},[295,1450,500],{"class":316},[295,1452,1383],{"class":301},[295,1454,674],{"class":301},[295,1456,1457],{"class":301},"    \"",[295,1459,1460],{"class":963},"ya29.xxx",[295,1462,1383],{"class":301},[295,1464,1073],{"class":301},[295,1466,1467,1469,1471,1473,1475,1478,1481,1483],{"class":297,"line":362},[295,1468,1378],{"class":301},[295,1470,514],{"class":316},[295,1472,1383],{"class":301},[295,1474,674],{"class":301},[295,1476,1477],{"class":301},"   \"",[295,1479,1480],{"class":963},"1//yyy",[295,1482,1383],{"class":301},[295,1484,1073],{"class":301},[295,1486,1487,1489,1491,1493,1495,1498,1501,1503],{"class":297,"line":376},[295,1488,1378],{"class":301},[295,1490,527],{"class":316},[295,1492,1383],{"class":301},[295,1494,674],{"class":301},[295,1496,1497],{"class":301},"      \"",[295,1499,1500],{"class":963},"2026-03-01T12:00:00.000Z",[295,1502,1383],{"class":301},[295,1504,1073],{"class":301},[295,1506,1507,1509,1511,1513,1515,1518,1520,1522,1524],{"class":297,"line":391},[295,1508,1378],{"class":301},[295,1510,543],{"class":316},[295,1512,1383],{"class":301},[295,1514,674],{"class":301},[295,1516,1517],{"class":301}," [",[295,1519,1383],{"class":301},[295,1521,1391],{"class":963},[295,1523,1383],{"class":301},[295,1525,1526],{"class":301},"],\n",[295,1528,1529,1531,1533,1535,1537,1539,1542,1544],{"class":297,"line":410},[295,1530,1378],{"class":301},[295,1532,553],{"class":316},[295,1534,1383],{"class":301},[295,1536,674],{"class":301},[295,1538,1497],{"class":301},[295,1540,1541],{"class":963},"2026-02-01T08:00:00.000Z",[295,1543,1383],{"class":301},[295,1545,1073],{"class":301},[295,1547,1548,1550,1552,1554,1556,1558,1561],{"class":297,"line":422},[295,1549,1378],{"class":301},[295,1551,563],{"class":316},[295,1553,1383],{"class":301},[295,1555,674],{"class":301},[295,1557,1388],{"class":301},[295,1559,1560],{"class":963},"2026-02-23T10:30:00.000Z",[295,1562,1563],{"class":301},"\"\n",[295,1565,1566],{"class":297,"line":434},[295,1567,437],{"class":301},[1569,1570,1572,1573,1576],"callout",{"icon":1571},"i-lucide-shield","The serialised session contains access and refresh tokens. It must be stored in an encrypted backend — ",[274,1574,1575],{},"SecureAuthStorage"," in Flutter, or your own encrypted implementation for other runtimes.",[278,1578],{},[281,1580,1582],{"id":1581},"multi-account-sessions","Multi-account sessions",[271,1584,1585,1588,1589,533,1592,1594],{},[274,1586,1587],{},"SessionRegistry"," maintains an in-memory map of active sessions keyed by ",[274,1590,1591],{},"user.id",[274,1593,207],{}," exposes the public API:",[286,1596,1598],{"className":288,"code":1597,"language":290,"meta":291,"style":291},"final accounts = Authyra.instance.accounts;\n\n// All signed-in accounts, sorted by last activity\nfinal users = await accounts.getAll();\n\n// Activate a different account\nawait accounts.switchTo(userId);\n\n// Sign out one account, keep others active\nawait accounts.signOut(userId);\n\n// Sign out all accounts\nawait accounts.signOutAll();\n\n// Remove expired sessions\nawait accounts.cleanExpired();\n",[274,1599,1600,1622,1626,1631,1654,1658,1663,1680,1684,1689,1704,1709,1715,1731,1736,1742],{"__ignoreMap":291},[295,1601,1602,1604,1607,1609,1611,1613,1615,1617,1620],{"class":297,"line":298},[295,1603,700],{"class":316},[295,1605,1606],{"class":309}," accounts ",[295,1608,662],{"class":301},[295,1610,712],{"class":305},[295,1612,631],{"class":301},[295,1614,717],{"class":309},[295,1616,631],{"class":301},[295,1618,1619],{"class":309},"accounts",[295,1621,344],{"class":301},[295,1623,1624],{"class":297,"line":313},[295,1625,1280],{"emptyLinePlaceholder":1279},[295,1627,1628],{"class":297,"line":333},[295,1629,1630],{"class":329},"// All signed-in accounts, sorted by last activity\n",[295,1632,1633,1635,1638,1640,1642,1645,1647,1650,1652],{"class":297,"line":347},[295,1634,700],{"class":316},[295,1636,1637],{"class":309}," users ",[295,1639,662],{"class":301},[295,1641,709],{"class":708},[295,1643,1644],{"class":309}," accounts",[295,1646,631],{"class":301},[295,1648,1649],{"class":649},"getAll",[295,1651,725],{"class":309},[295,1653,344],{"class":301},[295,1655,1656],{"class":297,"line":362},[295,1657,1280],{"emptyLinePlaceholder":1279},[295,1659,1660],{"class":297,"line":376},[295,1661,1662],{"class":329},"// Activate a different account\n",[295,1664,1665,1668,1670,1672,1675,1678],{"class":297,"line":391},[295,1666,1667],{"class":708},"await",[295,1669,1644],{"class":309},[295,1671,631],{"class":301},[295,1673,1674],{"class":649},"switchTo",[295,1676,1677],{"class":309},"(userId)",[295,1679,344],{"class":301},[295,1681,1682],{"class":297,"line":410},[295,1683,1280],{"emptyLinePlaceholder":1279},[295,1685,1686],{"class":297,"line":422},[295,1687,1688],{"class":329},"// Sign out one account, keep others active\n",[295,1690,1691,1693,1695,1697,1700,1702],{"class":297,"line":434},[295,1692,1667],{"class":708},[295,1694,1644],{"class":309},[295,1696,631],{"class":301},[295,1698,1699],{"class":649},"signOut",[295,1701,1677],{"class":309},[295,1703,344],{"class":301},[295,1705,1707],{"class":297,"line":1706},11,[295,1708,1280],{"emptyLinePlaceholder":1279},[295,1710,1712],{"class":297,"line":1711},12,[295,1713,1714],{"class":329},"// Sign out all accounts\n",[295,1716,1718,1720,1722,1724,1727,1729],{"class":297,"line":1717},13,[295,1719,1667],{"class":708},[295,1721,1644],{"class":309},[295,1723,631],{"class":301},[295,1725,1726],{"class":649},"signOutAll",[295,1728,725],{"class":309},[295,1730,344],{"class":301},[295,1732,1734],{"class":297,"line":1733},14,[295,1735,1280],{"emptyLinePlaceholder":1279},[295,1737,1739],{"class":297,"line":1738},15,[295,1740,1741],{"class":329},"// Remove expired sessions\n",[295,1743,1745,1747,1749,1751,1754,1756],{"class":297,"line":1744},16,[295,1746,1667],{"class":708},[295,1748,1644],{"class":309},[295,1750,631],{"class":301},[295,1752,1753],{"class":649},"cleanExpired",[295,1755,725],{"class":309},[295,1757,344],{"class":301},[271,1759,1760,1761,1764],{},"The active account limit is controlled by ",[274,1762,1763],{},"AuthConfig.maxAccounts"," (default: 5).",[278,1766],{},[281,1768,1770],{"id":1769},"linkedproviders",[274,1771,543],{},[271,1773,1774,1775,1777],{},"When a user signs in with multiple providers, all provider IDs are stored in ",[274,1776,543],{},". Use this to render a \"connected accounts\" UI:",[286,1779,1781],{"className":288,"code":1780,"language":290,"meta":291,"style":291},"final session = await Authyra.instance.getSession();\nfinal providers = session?.linkedProviders ?? [];\n\nif (session?.hasLinkedProvider('github') ?? false) {\n  showGitHubBadge();\n}\n",[274,1782,1783,1807,1830,1834,1859,1868],{"__ignoreMap":291},[295,1784,1785,1787,1789,1791,1793,1795,1797,1799,1801,1803,1805],{"class":297,"line":298},[295,1786,700],{"class":316},[295,1788,703],{"class":309},[295,1790,662],{"class":301},[295,1792,709],{"class":708},[295,1794,712],{"class":305},[295,1796,631],{"class":301},[295,1798,717],{"class":309},[295,1800,631],{"class":301},[295,1802,722],{"class":649},[295,1804,725],{"class":309},[295,1806,344],{"class":301},[295,1808,1809,1811,1814,1816,1818,1820,1823,1825,1828],{"class":297,"line":313},[295,1810,700],{"class":316},[295,1812,1813],{"class":309}," providers ",[295,1815,662],{"class":301},[295,1817,937],{"class":309},[295,1819,738],{"class":301},[295,1821,1822],{"class":309},"linkedProviders ",[295,1824,761],{"class":301},[295,1826,1827],{"class":309}," []",[295,1829,344],{"class":301},[295,1831,1832],{"class":297,"line":333},[295,1833,1280],{"emptyLinePlaceholder":1279},[295,1835,1836,1838,1840,1842,1845,1847,1850,1853,1855,1857],{"class":297,"line":347},[295,1837,732],{"class":708},[295,1839,735],{"class":309},[295,1841,738],{"class":301},[295,1843,1844],{"class":649},"hasLinkedProvider",[295,1846,743],{"class":309},[295,1848,1849],{"class":963},"'github'",[295,1851,1852],{"class":309},") ",[295,1854,761],{"class":301},[295,1856,764],{"class":301},[295,1858,767],{"class":309},[295,1860,1861,1864,1866],{"class":297,"line":362},[295,1862,1863],{"class":649},"  showGitHubBadge",[295,1865,725],{"class":309},[295,1867,344],{"class":301},[295,1869,1870],{"class":297,"line":376},[295,1871,437],{"class":309},[278,1873],{},[281,1875,1877],{"id":1876},"see-also","See also",[1879,1880,1881,1891,1897,1902],"ul",{},[1001,1882,1883,1887,1888,1890],{},[1884,1885,1886],"a",{"href":76},"Reactivity →"," — ",[274,1889,1026],{}," and synchronous state cache",[1001,1892,1893,1896],{},[1884,1894,1895],{"href":71},"Storage →"," — how sessions are persisted",[1001,1898,1899],{},[1884,1900,1901],{"href":138},"Token Refresh guide →",[1001,1903,1904],{},[1884,1905,1906],{"href":143},"Multi-Account guide →",[1908,1909,1910],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":291,"searchDepth":313,"depth":313,"links":1912},[1913,1914,1915,1921,1922,1923,1924,1925,1926,1927],{"id":283,"depth":313,"text":284},{"id":571,"depth":313,"text":572},{"id":585,"depth":313,"text":586,"children":1916},[1917,1918,1919,1920],{"id":590,"depth":333,"text":593},{"id":634,"depth":333,"text":637},{"id":794,"depth":333,"text":797},{"id":892,"depth":333,"text":895},{"id":992,"depth":313,"text":993},{"id":1133,"depth":313,"text":1134},{"id":1162,"depth":313,"text":1163},{"id":1352,"depth":313,"text":1353},{"id":1581,"depth":313,"text":1582},{"id":1769,"depth":313,"text":543},{"id":1876,"depth":313,"text":1877},"AuthSession lifecycle — fields, expiry helpers, token refresh, and multi-account support.","md",null,{},{"icon":68},{"title":1934,"description":1935},"Sessions | Authyra","How AuthSession works — lifecycle, expiry, shouldRefresh, refreshed(), multi-account with SessionRegistry.","Z3BPr_2DAj1GxhAINiyaIx-KIsG8V1zktUo5T2Jddik",[1938,1940],{"title":60,"path":61,"stem":62,"description":1939,"icon":63,"children":-1},"The AuthProvider interface — strategy types, sign-in, sign-out, and token refresh.",{"title":70,"path":71,"stem":72,"description":1941,"icon":73,"children":-1},"The AuthStorage interface — pluggable session persistence, security guidance, and implementing a custom backend.",1782700506039]