index-5ca0aadd.js 414 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194
  1. 'use strict';
  2. var util = require('@firebase/util');
  3. var app = require('@firebase/app');
  4. var tslib = require('tslib');
  5. var logger = require('@firebase/logger');
  6. var component = require('@firebase/component');
  7. /**
  8. * @license
  9. * Copyright 2021 Google LLC
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. */
  23. /**
  24. * An enum of factors that may be used for multifactor authentication.
  25. *
  26. * @public
  27. */
  28. const FactorId = {
  29. /** Phone as second factor */
  30. PHONE: 'phone',
  31. TOTP: 'totp'
  32. };
  33. /**
  34. * Enumeration of supported providers.
  35. *
  36. * @public
  37. */
  38. const ProviderId = {
  39. /** Facebook provider ID */
  40. FACEBOOK: 'facebook.com',
  41. /** GitHub provider ID */
  42. GITHUB: 'github.com',
  43. /** Google provider ID */
  44. GOOGLE: 'google.com',
  45. /** Password provider */
  46. PASSWORD: 'password',
  47. /** Phone provider */
  48. PHONE: 'phone',
  49. /** Twitter provider ID */
  50. TWITTER: 'twitter.com'
  51. };
  52. /**
  53. * Enumeration of supported sign-in methods.
  54. *
  55. * @public
  56. */
  57. const SignInMethod = {
  58. /** Email link sign in method */
  59. EMAIL_LINK: 'emailLink',
  60. /** Email/password sign in method */
  61. EMAIL_PASSWORD: 'password',
  62. /** Facebook sign in method */
  63. FACEBOOK: 'facebook.com',
  64. /** GitHub sign in method */
  65. GITHUB: 'github.com',
  66. /** Google sign in method */
  67. GOOGLE: 'google.com',
  68. /** Phone sign in method */
  69. PHONE: 'phone',
  70. /** Twitter sign in method */
  71. TWITTER: 'twitter.com'
  72. };
  73. /**
  74. * Enumeration of supported operation types.
  75. *
  76. * @public
  77. */
  78. const OperationType = {
  79. /** Operation involving linking an additional provider to an already signed-in user. */
  80. LINK: 'link',
  81. /** Operation involving using a provider to reauthenticate an already signed-in user. */
  82. REAUTHENTICATE: 'reauthenticate',
  83. /** Operation involving signing in a user. */
  84. SIGN_IN: 'signIn'
  85. };
  86. /**
  87. * An enumeration of the possible email action types.
  88. *
  89. * @public
  90. */
  91. const ActionCodeOperation = {
  92. /** The email link sign-in action. */
  93. EMAIL_SIGNIN: 'EMAIL_SIGNIN',
  94. /** The password reset action. */
  95. PASSWORD_RESET: 'PASSWORD_RESET',
  96. /** The email revocation action. */
  97. RECOVER_EMAIL: 'RECOVER_EMAIL',
  98. /** The revert second factor addition email action. */
  99. REVERT_SECOND_FACTOR_ADDITION: 'REVERT_SECOND_FACTOR_ADDITION',
  100. /** The revert second factor addition email action. */
  101. VERIFY_AND_CHANGE_EMAIL: 'VERIFY_AND_CHANGE_EMAIL',
  102. /** The email verification action. */
  103. VERIFY_EMAIL: 'VERIFY_EMAIL'
  104. };
  105. /**
  106. * @license
  107. * Copyright 2020 Google LLC
  108. *
  109. * Licensed under the Apache License, Version 2.0 (the "License");
  110. * you may not use this file except in compliance with the License.
  111. * You may obtain a copy of the License at
  112. *
  113. * http://www.apache.org/licenses/LICENSE-2.0
  114. *
  115. * Unless required by applicable law or agreed to in writing, software
  116. * distributed under the License is distributed on an "AS IS" BASIS,
  117. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  118. * See the License for the specific language governing permissions and
  119. * limitations under the License.
  120. */
  121. function _debugErrorMap() {
  122. return {
  123. ["admin-restricted-operation" /* AuthErrorCode.ADMIN_ONLY_OPERATION */]: 'This operation is restricted to administrators only.',
  124. ["argument-error" /* AuthErrorCode.ARGUMENT_ERROR */]: '',
  125. ["app-not-authorized" /* AuthErrorCode.APP_NOT_AUTHORIZED */]: "This app, identified by the domain where it's hosted, is not " +
  126. 'authorized to use Firebase Authentication with the provided API key. ' +
  127. 'Review your key configuration in the Google API console.',
  128. ["app-not-installed" /* AuthErrorCode.APP_NOT_INSTALLED */]: 'The requested mobile application corresponding to the identifier (' +
  129. 'Android package name or iOS bundle ID) provided is not installed on ' +
  130. 'this device.',
  131. ["captcha-check-failed" /* AuthErrorCode.CAPTCHA_CHECK_FAILED */]: 'The reCAPTCHA response token provided is either invalid, expired, ' +
  132. 'already used or the domain associated with it does not match the list ' +
  133. 'of whitelisted domains.',
  134. ["code-expired" /* AuthErrorCode.CODE_EXPIRED */]: 'The SMS code has expired. Please re-send the verification code to try ' +
  135. 'again.',
  136. ["cordova-not-ready" /* AuthErrorCode.CORDOVA_NOT_READY */]: 'Cordova framework is not ready.',
  137. ["cors-unsupported" /* AuthErrorCode.CORS_UNSUPPORTED */]: 'This browser is not supported.',
  138. ["credential-already-in-use" /* AuthErrorCode.CREDENTIAL_ALREADY_IN_USE */]: 'This credential is already associated with a different user account.',
  139. ["custom-token-mismatch" /* AuthErrorCode.CREDENTIAL_MISMATCH */]: 'The custom token corresponds to a different audience.',
  140. ["requires-recent-login" /* AuthErrorCode.CREDENTIAL_TOO_OLD_LOGIN_AGAIN */]: 'This operation is sensitive and requires recent authentication. Log in ' +
  141. 'again before retrying this request.',
  142. ["dependent-sdk-initialized-before-auth" /* AuthErrorCode.DEPENDENT_SDK_INIT_BEFORE_AUTH */]: 'Another Firebase SDK was initialized and is trying to use Auth before Auth is ' +
  143. 'initialized. Please be sure to call `initializeAuth` or `getAuth` before ' +
  144. 'starting any other Firebase SDK.',
  145. ["dynamic-link-not-activated" /* AuthErrorCode.DYNAMIC_LINK_NOT_ACTIVATED */]: 'Please activate Dynamic Links in the Firebase Console and agree to the terms and ' +
  146. 'conditions.',
  147. ["email-change-needs-verification" /* AuthErrorCode.EMAIL_CHANGE_NEEDS_VERIFICATION */]: 'Multi-factor users must always have a verified email.',
  148. ["email-already-in-use" /* AuthErrorCode.EMAIL_EXISTS */]: 'The email address is already in use by another account.',
  149. ["emulator-config-failed" /* AuthErrorCode.EMULATOR_CONFIG_FAILED */]: 'Auth instance has already been used to make a network call. Auth can ' +
  150. 'no longer be configured to use the emulator. Try calling ' +
  151. '"connectAuthEmulator()" sooner.',
  152. ["expired-action-code" /* AuthErrorCode.EXPIRED_OOB_CODE */]: 'The action code has expired.',
  153. ["cancelled-popup-request" /* AuthErrorCode.EXPIRED_POPUP_REQUEST */]: 'This operation has been cancelled due to another conflicting popup being opened.',
  154. ["internal-error" /* AuthErrorCode.INTERNAL_ERROR */]: 'An internal AuthError has occurred.',
  155. ["invalid-app-credential" /* AuthErrorCode.INVALID_APP_CREDENTIAL */]: 'The phone verification request contains an invalid application verifier.' +
  156. ' The reCAPTCHA token response is either invalid or expired.',
  157. ["invalid-app-id" /* AuthErrorCode.INVALID_APP_ID */]: 'The mobile app identifier is not registed for the current project.',
  158. ["invalid-user-token" /* AuthErrorCode.INVALID_AUTH */]: "This user's credential isn't valid for this project. This can happen " +
  159. "if the user's token has been tampered with, or if the user isn't for " +
  160. 'the project associated with this API key.',
  161. ["invalid-auth-event" /* AuthErrorCode.INVALID_AUTH_EVENT */]: 'An internal AuthError has occurred.',
  162. ["invalid-verification-code" /* AuthErrorCode.INVALID_CODE */]: 'The SMS verification code used to create the phone auth credential is ' +
  163. 'invalid. Please resend the verification code sms and be sure to use the ' +
  164. 'verification code provided by the user.',
  165. ["invalid-continue-uri" /* AuthErrorCode.INVALID_CONTINUE_URI */]: 'The continue URL provided in the request is invalid.',
  166. ["invalid-cordova-configuration" /* AuthErrorCode.INVALID_CORDOVA_CONFIGURATION */]: 'The following Cordova plugins must be installed to enable OAuth sign-in: ' +
  167. 'cordova-plugin-buildinfo, cordova-universal-links-plugin, ' +
  168. 'cordova-plugin-browsertab, cordova-plugin-inappbrowser and ' +
  169. 'cordova-plugin-customurlscheme.',
  170. ["invalid-custom-token" /* AuthErrorCode.INVALID_CUSTOM_TOKEN */]: 'The custom token format is incorrect. Please check the documentation.',
  171. ["invalid-dynamic-link-domain" /* AuthErrorCode.INVALID_DYNAMIC_LINK_DOMAIN */]: 'The provided dynamic link domain is not configured or authorized for the current project.',
  172. ["invalid-email" /* AuthErrorCode.INVALID_EMAIL */]: 'The email address is badly formatted.',
  173. ["invalid-emulator-scheme" /* AuthErrorCode.INVALID_EMULATOR_SCHEME */]: 'Emulator URL must start with a valid scheme (http:// or https://).',
  174. ["invalid-api-key" /* AuthErrorCode.INVALID_API_KEY */]: 'Your API key is invalid, please check you have copied it correctly.',
  175. ["invalid-cert-hash" /* AuthErrorCode.INVALID_CERT_HASH */]: 'The SHA-1 certificate hash provided is invalid.',
  176. ["invalid-credential" /* AuthErrorCode.INVALID_IDP_RESPONSE */]: 'The supplied auth credential is malformed or has expired.',
  177. ["invalid-message-payload" /* AuthErrorCode.INVALID_MESSAGE_PAYLOAD */]: 'The email template corresponding to this action contains invalid characters in its message. ' +
  178. 'Please fix by going to the Auth email templates section in the Firebase Console.',
  179. ["invalid-multi-factor-session" /* AuthErrorCode.INVALID_MFA_SESSION */]: 'The request does not contain a valid proof of first factor successful sign-in.',
  180. ["invalid-oauth-provider" /* AuthErrorCode.INVALID_OAUTH_PROVIDER */]: 'EmailAuthProvider is not supported for this operation. This operation ' +
  181. 'only supports OAuth providers.',
  182. ["invalid-oauth-client-id" /* AuthErrorCode.INVALID_OAUTH_CLIENT_ID */]: 'The OAuth client ID provided is either invalid or does not match the ' +
  183. 'specified API key.',
  184. ["unauthorized-domain" /* AuthErrorCode.INVALID_ORIGIN */]: 'This domain is not authorized for OAuth operations for your Firebase ' +
  185. 'project. Edit the list of authorized domains from the Firebase console.',
  186. ["invalid-action-code" /* AuthErrorCode.INVALID_OOB_CODE */]: 'The action code is invalid. This can happen if the code is malformed, ' +
  187. 'expired, or has already been used.',
  188. ["wrong-password" /* AuthErrorCode.INVALID_PASSWORD */]: 'The password is invalid or the user does not have a password.',
  189. ["invalid-persistence-type" /* AuthErrorCode.INVALID_PERSISTENCE */]: 'The specified persistence type is invalid. It can only be local, session or none.',
  190. ["invalid-phone-number" /* AuthErrorCode.INVALID_PHONE_NUMBER */]: 'The format of the phone number provided is incorrect. Please enter the ' +
  191. 'phone number in a format that can be parsed into E.164 format. E.164 ' +
  192. 'phone numbers are written in the format [+][country code][subscriber ' +
  193. 'number including area code].',
  194. ["invalid-provider-id" /* AuthErrorCode.INVALID_PROVIDER_ID */]: 'The specified provider ID is invalid.',
  195. ["invalid-recipient-email" /* AuthErrorCode.INVALID_RECIPIENT_EMAIL */]: 'The email corresponding to this action failed to send as the provided ' +
  196. 'recipient email address is invalid.',
  197. ["invalid-sender" /* AuthErrorCode.INVALID_SENDER */]: 'The email template corresponding to this action contains an invalid sender email or name. ' +
  198. 'Please fix by going to the Auth email templates section in the Firebase Console.',
  199. ["invalid-verification-id" /* AuthErrorCode.INVALID_SESSION_INFO */]: 'The verification ID used to create the phone auth credential is invalid.',
  200. ["invalid-tenant-id" /* AuthErrorCode.INVALID_TENANT_ID */]: "The Auth instance's tenant ID is invalid.",
  201. ["login-blocked" /* AuthErrorCode.LOGIN_BLOCKED */]: 'Login blocked by user-provided method: {$originalMessage}',
  202. ["missing-android-pkg-name" /* AuthErrorCode.MISSING_ANDROID_PACKAGE_NAME */]: 'An Android Package Name must be provided if the Android App is required to be installed.',
  203. ["auth-domain-config-required" /* AuthErrorCode.MISSING_AUTH_DOMAIN */]: 'Be sure to include authDomain when calling firebase.initializeApp(), ' +
  204. 'by following the instructions in the Firebase console.',
  205. ["missing-app-credential" /* AuthErrorCode.MISSING_APP_CREDENTIAL */]: 'The phone verification request is missing an application verifier ' +
  206. 'assertion. A reCAPTCHA response token needs to be provided.',
  207. ["missing-verification-code" /* AuthErrorCode.MISSING_CODE */]: 'The phone auth credential was created with an empty SMS verification code.',
  208. ["missing-continue-uri" /* AuthErrorCode.MISSING_CONTINUE_URI */]: 'A continue URL must be provided in the request.',
  209. ["missing-iframe-start" /* AuthErrorCode.MISSING_IFRAME_START */]: 'An internal AuthError has occurred.',
  210. ["missing-ios-bundle-id" /* AuthErrorCode.MISSING_IOS_BUNDLE_ID */]: 'An iOS Bundle ID must be provided if an App Store ID is provided.',
  211. ["missing-or-invalid-nonce" /* AuthErrorCode.MISSING_OR_INVALID_NONCE */]: 'The request does not contain a valid nonce. This can occur if the ' +
  212. 'SHA-256 hash of the provided raw nonce does not match the hashed nonce ' +
  213. 'in the ID token payload.',
  214. ["missing-password" /* AuthErrorCode.MISSING_PASSWORD */]: 'A non-empty password must be provided',
  215. ["missing-multi-factor-info" /* AuthErrorCode.MISSING_MFA_INFO */]: 'No second factor identifier is provided.',
  216. ["missing-multi-factor-session" /* AuthErrorCode.MISSING_MFA_SESSION */]: 'The request is missing proof of first factor successful sign-in.',
  217. ["missing-phone-number" /* AuthErrorCode.MISSING_PHONE_NUMBER */]: 'To send verification codes, provide a phone number for the recipient.',
  218. ["missing-verification-id" /* AuthErrorCode.MISSING_SESSION_INFO */]: 'The phone auth credential was created with an empty verification ID.',
  219. ["app-deleted" /* AuthErrorCode.MODULE_DESTROYED */]: 'This instance of FirebaseApp has been deleted.',
  220. ["multi-factor-info-not-found" /* AuthErrorCode.MFA_INFO_NOT_FOUND */]: 'The user does not have a second factor matching the identifier provided.',
  221. ["multi-factor-auth-required" /* AuthErrorCode.MFA_REQUIRED */]: 'Proof of ownership of a second factor is required to complete sign-in.',
  222. ["account-exists-with-different-credential" /* AuthErrorCode.NEED_CONFIRMATION */]: 'An account already exists with the same email address but different ' +
  223. 'sign-in credentials. Sign in using a provider associated with this ' +
  224. 'email address.',
  225. ["network-request-failed" /* AuthErrorCode.NETWORK_REQUEST_FAILED */]: 'A network AuthError (such as timeout, interrupted connection or unreachable host) has occurred.',
  226. ["no-auth-event" /* AuthErrorCode.NO_AUTH_EVENT */]: 'An internal AuthError has occurred.',
  227. ["no-such-provider" /* AuthErrorCode.NO_SUCH_PROVIDER */]: 'User was not linked to an account with the given provider.',
  228. ["null-user" /* AuthErrorCode.NULL_USER */]: 'A null user object was provided as the argument for an operation which ' +
  229. 'requires a non-null user object.',
  230. ["operation-not-allowed" /* AuthErrorCode.OPERATION_NOT_ALLOWED */]: 'The given sign-in provider is disabled for this Firebase project. ' +
  231. 'Enable it in the Firebase console, under the sign-in method tab of the ' +
  232. 'Auth section.',
  233. ["operation-not-supported-in-this-environment" /* AuthErrorCode.OPERATION_NOT_SUPPORTED */]: 'This operation is not supported in the environment this application is ' +
  234. 'running on. "location.protocol" must be http, https or chrome-extension' +
  235. ' and web storage must be enabled.',
  236. ["popup-blocked" /* AuthErrorCode.POPUP_BLOCKED */]: 'Unable to establish a connection with the popup. It may have been blocked by the browser.',
  237. ["popup-closed-by-user" /* AuthErrorCode.POPUP_CLOSED_BY_USER */]: 'The popup has been closed by the user before finalizing the operation.',
  238. ["provider-already-linked" /* AuthErrorCode.PROVIDER_ALREADY_LINKED */]: 'User can only be linked to one identity for the given provider.',
  239. ["quota-exceeded" /* AuthErrorCode.QUOTA_EXCEEDED */]: "The project's quota for this operation has been exceeded.",
  240. ["redirect-cancelled-by-user" /* AuthErrorCode.REDIRECT_CANCELLED_BY_USER */]: 'The redirect operation has been cancelled by the user before finalizing.',
  241. ["redirect-operation-pending" /* AuthErrorCode.REDIRECT_OPERATION_PENDING */]: 'A redirect sign-in operation is already pending.',
  242. ["rejected-credential" /* AuthErrorCode.REJECTED_CREDENTIAL */]: 'The request contains malformed or mismatching credentials.',
  243. ["second-factor-already-in-use" /* AuthErrorCode.SECOND_FACTOR_ALREADY_ENROLLED */]: 'The second factor is already enrolled on this account.',
  244. ["maximum-second-factor-count-exceeded" /* AuthErrorCode.SECOND_FACTOR_LIMIT_EXCEEDED */]: 'The maximum allowed number of second factors on a user has been exceeded.',
  245. ["tenant-id-mismatch" /* AuthErrorCode.TENANT_ID_MISMATCH */]: "The provided tenant ID does not match the Auth instance's tenant ID",
  246. ["timeout" /* AuthErrorCode.TIMEOUT */]: 'The operation has timed out.',
  247. ["user-token-expired" /* AuthErrorCode.TOKEN_EXPIRED */]: "The user's credential is no longer valid. The user must sign in again.",
  248. ["too-many-requests" /* AuthErrorCode.TOO_MANY_ATTEMPTS_TRY_LATER */]: 'We have blocked all requests from this device due to unusual activity. ' +
  249. 'Try again later.',
  250. ["unauthorized-continue-uri" /* AuthErrorCode.UNAUTHORIZED_DOMAIN */]: 'The domain of the continue URL is not whitelisted. Please whitelist ' +
  251. 'the domain in the Firebase console.',
  252. ["unsupported-first-factor" /* AuthErrorCode.UNSUPPORTED_FIRST_FACTOR */]: 'Enrolling a second factor or signing in with a multi-factor account requires sign-in with a supported first factor.',
  253. ["unsupported-persistence-type" /* AuthErrorCode.UNSUPPORTED_PERSISTENCE */]: 'The current environment does not support the specified persistence type.',
  254. ["unsupported-tenant-operation" /* AuthErrorCode.UNSUPPORTED_TENANT_OPERATION */]: 'This operation is not supported in a multi-tenant context.',
  255. ["unverified-email" /* AuthErrorCode.UNVERIFIED_EMAIL */]: 'The operation requires a verified email.',
  256. ["user-cancelled" /* AuthErrorCode.USER_CANCELLED */]: 'The user did not grant your application the permissions it requested.',
  257. ["user-not-found" /* AuthErrorCode.USER_DELETED */]: 'There is no user record corresponding to this identifier. The user may ' +
  258. 'have been deleted.',
  259. ["user-disabled" /* AuthErrorCode.USER_DISABLED */]: 'The user account has been disabled by an administrator.',
  260. ["user-mismatch" /* AuthErrorCode.USER_MISMATCH */]: 'The supplied credentials do not correspond to the previously signed in user.',
  261. ["user-signed-out" /* AuthErrorCode.USER_SIGNED_OUT */]: '',
  262. ["weak-password" /* AuthErrorCode.WEAK_PASSWORD */]: 'The password must be 6 characters long or more.',
  263. ["web-storage-unsupported" /* AuthErrorCode.WEB_STORAGE_UNSUPPORTED */]: 'This browser is not supported or 3rd party cookies and data may be disabled.',
  264. ["already-initialized" /* AuthErrorCode.ALREADY_INITIALIZED */]: 'initializeAuth() has already been called with ' +
  265. 'different options. To avoid this error, call initializeAuth() with the ' +
  266. 'same options as when it was originally called, or call getAuth() to return the' +
  267. ' already initialized instance.',
  268. ["missing-recaptcha-token" /* AuthErrorCode.MISSING_RECAPTCHA_TOKEN */]: 'The reCAPTCHA token is missing when sending request to the backend.',
  269. ["invalid-recaptcha-token" /* AuthErrorCode.INVALID_RECAPTCHA_TOKEN */]: 'The reCAPTCHA token is invalid when sending request to the backend.',
  270. ["invalid-recaptcha-action" /* AuthErrorCode.INVALID_RECAPTCHA_ACTION */]: 'The reCAPTCHA action is invalid when sending request to the backend.',
  271. ["recaptcha-not-enabled" /* AuthErrorCode.RECAPTCHA_NOT_ENABLED */]: 'reCAPTCHA Enterprise integration is not enabled for this project.',
  272. ["missing-client-type" /* AuthErrorCode.MISSING_CLIENT_TYPE */]: 'The reCAPTCHA client type is missing when sending request to the backend.',
  273. ["missing-recaptcha-version" /* AuthErrorCode.MISSING_RECAPTCHA_VERSION */]: 'The reCAPTCHA version is missing when sending request to the backend.',
  274. ["invalid-req-type" /* AuthErrorCode.INVALID_REQ_TYPE */]: 'Invalid request parameters.',
  275. ["invalid-recaptcha-version" /* AuthErrorCode.INVALID_RECAPTCHA_VERSION */]: 'The reCAPTCHA version is invalid when sending request to the backend.'
  276. };
  277. }
  278. function _prodErrorMap() {
  279. // We will include this one message in the prod error map since by the very
  280. // nature of this error, developers will never be able to see the message
  281. // using the debugErrorMap (which is installed during auth initialization).
  282. return {
  283. ["dependent-sdk-initialized-before-auth" /* AuthErrorCode.DEPENDENT_SDK_INIT_BEFORE_AUTH */]: 'Another Firebase SDK was initialized and is trying to use Auth before Auth is ' +
  284. 'initialized. Please be sure to call `initializeAuth` or `getAuth` before ' +
  285. 'starting any other Firebase SDK.'
  286. };
  287. }
  288. /**
  289. * A verbose error map with detailed descriptions for most error codes.
  290. *
  291. * See discussion at {@link AuthErrorMap}
  292. *
  293. * @public
  294. */
  295. const debugErrorMap = _debugErrorMap;
  296. /**
  297. * A minimal error map with all verbose error messages stripped.
  298. *
  299. * See discussion at {@link AuthErrorMap}
  300. *
  301. * @public
  302. */
  303. const prodErrorMap = _prodErrorMap;
  304. const _DEFAULT_AUTH_ERROR_FACTORY = new util.ErrorFactory('auth', 'Firebase', _prodErrorMap());
  305. /**
  306. * A map of potential `Auth` error codes, for easier comparison with errors
  307. * thrown by the SDK.
  308. *
  309. * @remarks
  310. * Note that you can't tree-shake individual keys
  311. * in the map, so by using the map you might substantially increase your
  312. * bundle size.
  313. *
  314. * @public
  315. */
  316. const AUTH_ERROR_CODES_MAP_DO_NOT_USE_INTERNALLY = {
  317. ADMIN_ONLY_OPERATION: 'auth/admin-restricted-operation',
  318. ARGUMENT_ERROR: 'auth/argument-error',
  319. APP_NOT_AUTHORIZED: 'auth/app-not-authorized',
  320. APP_NOT_INSTALLED: 'auth/app-not-installed',
  321. CAPTCHA_CHECK_FAILED: 'auth/captcha-check-failed',
  322. CODE_EXPIRED: 'auth/code-expired',
  323. CORDOVA_NOT_READY: 'auth/cordova-not-ready',
  324. CORS_UNSUPPORTED: 'auth/cors-unsupported',
  325. CREDENTIAL_ALREADY_IN_USE: 'auth/credential-already-in-use',
  326. CREDENTIAL_MISMATCH: 'auth/custom-token-mismatch',
  327. CREDENTIAL_TOO_OLD_LOGIN_AGAIN: 'auth/requires-recent-login',
  328. DEPENDENT_SDK_INIT_BEFORE_AUTH: 'auth/dependent-sdk-initialized-before-auth',
  329. DYNAMIC_LINK_NOT_ACTIVATED: 'auth/dynamic-link-not-activated',
  330. EMAIL_CHANGE_NEEDS_VERIFICATION: 'auth/email-change-needs-verification',
  331. EMAIL_EXISTS: 'auth/email-already-in-use',
  332. EMULATOR_CONFIG_FAILED: 'auth/emulator-config-failed',
  333. EXPIRED_OOB_CODE: 'auth/expired-action-code',
  334. EXPIRED_POPUP_REQUEST: 'auth/cancelled-popup-request',
  335. INTERNAL_ERROR: 'auth/internal-error',
  336. INVALID_API_KEY: 'auth/invalid-api-key',
  337. INVALID_APP_CREDENTIAL: 'auth/invalid-app-credential',
  338. INVALID_APP_ID: 'auth/invalid-app-id',
  339. INVALID_AUTH: 'auth/invalid-user-token',
  340. INVALID_AUTH_EVENT: 'auth/invalid-auth-event',
  341. INVALID_CERT_HASH: 'auth/invalid-cert-hash',
  342. INVALID_CODE: 'auth/invalid-verification-code',
  343. INVALID_CONTINUE_URI: 'auth/invalid-continue-uri',
  344. INVALID_CORDOVA_CONFIGURATION: 'auth/invalid-cordova-configuration',
  345. INVALID_CUSTOM_TOKEN: 'auth/invalid-custom-token',
  346. INVALID_DYNAMIC_LINK_DOMAIN: 'auth/invalid-dynamic-link-domain',
  347. INVALID_EMAIL: 'auth/invalid-email',
  348. INVALID_EMULATOR_SCHEME: 'auth/invalid-emulator-scheme',
  349. INVALID_IDP_RESPONSE: 'auth/invalid-credential',
  350. INVALID_MESSAGE_PAYLOAD: 'auth/invalid-message-payload',
  351. INVALID_MFA_SESSION: 'auth/invalid-multi-factor-session',
  352. INVALID_OAUTH_CLIENT_ID: 'auth/invalid-oauth-client-id',
  353. INVALID_OAUTH_PROVIDER: 'auth/invalid-oauth-provider',
  354. INVALID_OOB_CODE: 'auth/invalid-action-code',
  355. INVALID_ORIGIN: 'auth/unauthorized-domain',
  356. INVALID_PASSWORD: 'auth/wrong-password',
  357. INVALID_PERSISTENCE: 'auth/invalid-persistence-type',
  358. INVALID_PHONE_NUMBER: 'auth/invalid-phone-number',
  359. INVALID_PROVIDER_ID: 'auth/invalid-provider-id',
  360. INVALID_RECIPIENT_EMAIL: 'auth/invalid-recipient-email',
  361. INVALID_SENDER: 'auth/invalid-sender',
  362. INVALID_SESSION_INFO: 'auth/invalid-verification-id',
  363. INVALID_TENANT_ID: 'auth/invalid-tenant-id',
  364. MFA_INFO_NOT_FOUND: 'auth/multi-factor-info-not-found',
  365. MFA_REQUIRED: 'auth/multi-factor-auth-required',
  366. MISSING_ANDROID_PACKAGE_NAME: 'auth/missing-android-pkg-name',
  367. MISSING_APP_CREDENTIAL: 'auth/missing-app-credential',
  368. MISSING_AUTH_DOMAIN: 'auth/auth-domain-config-required',
  369. MISSING_CODE: 'auth/missing-verification-code',
  370. MISSING_CONTINUE_URI: 'auth/missing-continue-uri',
  371. MISSING_IFRAME_START: 'auth/missing-iframe-start',
  372. MISSING_IOS_BUNDLE_ID: 'auth/missing-ios-bundle-id',
  373. MISSING_OR_INVALID_NONCE: 'auth/missing-or-invalid-nonce',
  374. MISSING_MFA_INFO: 'auth/missing-multi-factor-info',
  375. MISSING_MFA_SESSION: 'auth/missing-multi-factor-session',
  376. MISSING_PHONE_NUMBER: 'auth/missing-phone-number',
  377. MISSING_SESSION_INFO: 'auth/missing-verification-id',
  378. MODULE_DESTROYED: 'auth/app-deleted',
  379. NEED_CONFIRMATION: 'auth/account-exists-with-different-credential',
  380. NETWORK_REQUEST_FAILED: 'auth/network-request-failed',
  381. NULL_USER: 'auth/null-user',
  382. NO_AUTH_EVENT: 'auth/no-auth-event',
  383. NO_SUCH_PROVIDER: 'auth/no-such-provider',
  384. OPERATION_NOT_ALLOWED: 'auth/operation-not-allowed',
  385. OPERATION_NOT_SUPPORTED: 'auth/operation-not-supported-in-this-environment',
  386. POPUP_BLOCKED: 'auth/popup-blocked',
  387. POPUP_CLOSED_BY_USER: 'auth/popup-closed-by-user',
  388. PROVIDER_ALREADY_LINKED: 'auth/provider-already-linked',
  389. QUOTA_EXCEEDED: 'auth/quota-exceeded',
  390. REDIRECT_CANCELLED_BY_USER: 'auth/redirect-cancelled-by-user',
  391. REDIRECT_OPERATION_PENDING: 'auth/redirect-operation-pending',
  392. REJECTED_CREDENTIAL: 'auth/rejected-credential',
  393. SECOND_FACTOR_ALREADY_ENROLLED: 'auth/second-factor-already-in-use',
  394. SECOND_FACTOR_LIMIT_EXCEEDED: 'auth/maximum-second-factor-count-exceeded',
  395. TENANT_ID_MISMATCH: 'auth/tenant-id-mismatch',
  396. TIMEOUT: 'auth/timeout',
  397. TOKEN_EXPIRED: 'auth/user-token-expired',
  398. TOO_MANY_ATTEMPTS_TRY_LATER: 'auth/too-many-requests',
  399. UNAUTHORIZED_DOMAIN: 'auth/unauthorized-continue-uri',
  400. UNSUPPORTED_FIRST_FACTOR: 'auth/unsupported-first-factor',
  401. UNSUPPORTED_PERSISTENCE: 'auth/unsupported-persistence-type',
  402. UNSUPPORTED_TENANT_OPERATION: 'auth/unsupported-tenant-operation',
  403. UNVERIFIED_EMAIL: 'auth/unverified-email',
  404. USER_CANCELLED: 'auth/user-cancelled',
  405. USER_DELETED: 'auth/user-not-found',
  406. USER_DISABLED: 'auth/user-disabled',
  407. USER_MISMATCH: 'auth/user-mismatch',
  408. USER_SIGNED_OUT: 'auth/user-signed-out',
  409. WEAK_PASSWORD: 'auth/weak-password',
  410. WEB_STORAGE_UNSUPPORTED: 'auth/web-storage-unsupported',
  411. ALREADY_INITIALIZED: 'auth/already-initialized',
  412. RECAPTCHA_NOT_ENABLED: 'auth/recaptcha-not-enabled',
  413. MISSING_RECAPTCHA_TOKEN: 'auth/missing-recaptcha-token',
  414. INVALID_RECAPTCHA_TOKEN: 'auth/invalid-recaptcha-token',
  415. INVALID_RECAPTCHA_ACTION: 'auth/invalid-recaptcha-action',
  416. MISSING_CLIENT_TYPE: 'auth/missing-client-type',
  417. MISSING_RECAPTCHA_VERSION: 'auth/missing-recaptcha-version',
  418. INVALID_RECAPTCHA_VERSION: 'auth/invalid-recaptcha-version',
  419. INVALID_REQ_TYPE: 'auth/invalid-req-type'
  420. };
  421. /**
  422. * @license
  423. * Copyright 2020 Google LLC
  424. *
  425. * Licensed under the Apache License, Version 2.0 (the "License");
  426. * you may not use this file except in compliance with the License.
  427. * You may obtain a copy of the License at
  428. *
  429. * http://www.apache.org/licenses/LICENSE-2.0
  430. *
  431. * Unless required by applicable law or agreed to in writing, software
  432. * distributed under the License is distributed on an "AS IS" BASIS,
  433. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  434. * See the License for the specific language governing permissions and
  435. * limitations under the License.
  436. */
  437. const logClient = new logger.Logger('@firebase/auth');
  438. function _logWarn(msg, ...args) {
  439. if (logClient.logLevel <= logger.LogLevel.WARN) {
  440. logClient.warn(`Auth (${app.SDK_VERSION}): ${msg}`, ...args);
  441. }
  442. }
  443. function _logError(msg, ...args) {
  444. if (logClient.logLevel <= logger.LogLevel.ERROR) {
  445. logClient.error(`Auth (${app.SDK_VERSION}): ${msg}`, ...args);
  446. }
  447. }
  448. /**
  449. * @license
  450. * Copyright 2020 Google LLC
  451. *
  452. * Licensed under the Apache License, Version 2.0 (the "License");
  453. * you may not use this file except in compliance with the License.
  454. * You may obtain a copy of the License at
  455. *
  456. * http://www.apache.org/licenses/LICENSE-2.0
  457. *
  458. * Unless required by applicable law or agreed to in writing, software
  459. * distributed under the License is distributed on an "AS IS" BASIS,
  460. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  461. * See the License for the specific language governing permissions and
  462. * limitations under the License.
  463. */
  464. function _fail(authOrCode, ...rest) {
  465. throw createErrorInternal(authOrCode, ...rest);
  466. }
  467. function _createError(authOrCode, ...rest) {
  468. return createErrorInternal(authOrCode, ...rest);
  469. }
  470. function _errorWithCustomMessage(auth, code, message) {
  471. const errorMap = Object.assign(Object.assign({}, prodErrorMap()), { [code]: message });
  472. const factory = new util.ErrorFactory('auth', 'Firebase', errorMap);
  473. return factory.create(code, {
  474. appName: auth.name
  475. });
  476. }
  477. function _assertInstanceOf(auth, object, instance) {
  478. const constructorInstance = instance;
  479. if (!(object instanceof constructorInstance)) {
  480. if (constructorInstance.name !== object.constructor.name) {
  481. _fail(auth, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  482. }
  483. throw _errorWithCustomMessage(auth, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */, `Type of ${object.constructor.name} does not match expected instance.` +
  484. `Did you pass a reference from a different Auth SDK?`);
  485. }
  486. }
  487. function createErrorInternal(authOrCode, ...rest) {
  488. if (typeof authOrCode !== 'string') {
  489. const code = rest[0];
  490. const fullParams = [...rest.slice(1)];
  491. if (fullParams[0]) {
  492. fullParams[0].appName = authOrCode.name;
  493. }
  494. return authOrCode._errorFactory.create(code, ...fullParams);
  495. }
  496. return _DEFAULT_AUTH_ERROR_FACTORY.create(authOrCode, ...rest);
  497. }
  498. function _assert(assertion, authOrCode, ...rest) {
  499. if (!assertion) {
  500. throw createErrorInternal(authOrCode, ...rest);
  501. }
  502. }
  503. /**
  504. * Unconditionally fails, throwing an internal error with the given message.
  505. *
  506. * @param failure type of failure encountered
  507. * @throws Error
  508. */
  509. function debugFail(failure) {
  510. // Log the failure in addition to throw an exception, just in case the
  511. // exception is swallowed.
  512. const message = `INTERNAL ASSERTION FAILED: ` + failure;
  513. _logError(message);
  514. // NOTE: We don't use FirebaseError here because these are internal failures
  515. // that cannot be handled by the user. (Also it would create a circular
  516. // dependency between the error and assert modules which doesn't work.)
  517. throw new Error(message);
  518. }
  519. /**
  520. * Fails if the given assertion condition is false, throwing an Error with the
  521. * given message if it did.
  522. *
  523. * @param assertion
  524. * @param message
  525. */
  526. function debugAssert(assertion, message) {
  527. if (!assertion) {
  528. debugFail(message);
  529. }
  530. }
  531. /**
  532. * @license
  533. * Copyright 2020 Google LLC
  534. *
  535. * Licensed under the Apache License, Version 2.0 (the "License");
  536. * you may not use this file except in compliance with the License.
  537. * You may obtain a copy of the License at
  538. *
  539. * http://www.apache.org/licenses/LICENSE-2.0
  540. *
  541. * Unless required by applicable law or agreed to in writing, software
  542. * distributed under the License is distributed on an "AS IS" BASIS,
  543. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  544. * See the License for the specific language governing permissions and
  545. * limitations under the License.
  546. */
  547. function _getCurrentUrl() {
  548. var _a;
  549. return (typeof self !== 'undefined' && ((_a = self.location) === null || _a === void 0 ? void 0 : _a.href)) || '';
  550. }
  551. function _isHttpOrHttps() {
  552. return _getCurrentScheme() === 'http:' || _getCurrentScheme() === 'https:';
  553. }
  554. function _getCurrentScheme() {
  555. var _a;
  556. return (typeof self !== 'undefined' && ((_a = self.location) === null || _a === void 0 ? void 0 : _a.protocol)) || null;
  557. }
  558. /**
  559. * @license
  560. * Copyright 2020 Google LLC
  561. *
  562. * Licensed under the Apache License, Version 2.0 (the "License");
  563. * you may not use this file except in compliance with the License.
  564. * You may obtain a copy of the License at
  565. *
  566. * http://www.apache.org/licenses/LICENSE-2.0
  567. *
  568. * Unless required by applicable law or agreed to in writing, software
  569. * distributed under the License is distributed on an "AS IS" BASIS,
  570. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  571. * See the License for the specific language governing permissions and
  572. * limitations under the License.
  573. */
  574. /**
  575. * Determine whether the browser is working online
  576. */
  577. function _isOnline() {
  578. if (typeof navigator !== 'undefined' &&
  579. navigator &&
  580. 'onLine' in navigator &&
  581. typeof navigator.onLine === 'boolean' &&
  582. // Apply only for traditional web apps and Chrome extensions.
  583. // This is especially true for Cordova apps which have unreliable
  584. // navigator.onLine behavior unless cordova-plugin-network-information is
  585. // installed which overwrites the native navigator.onLine value and
  586. // defines navigator.connection.
  587. (_isHttpOrHttps() || util.isBrowserExtension() || 'connection' in navigator)) {
  588. return navigator.onLine;
  589. }
  590. // If we can't determine the state, assume it is online.
  591. return true;
  592. }
  593. function _getUserLanguage() {
  594. if (typeof navigator === 'undefined') {
  595. return null;
  596. }
  597. const navigatorLanguage = navigator;
  598. return (
  599. // Most reliable, but only supported in Chrome/Firefox.
  600. (navigatorLanguage.languages && navigatorLanguage.languages[0]) ||
  601. // Supported in most browsers, but returns the language of the browser
  602. // UI, not the language set in browser settings.
  603. navigatorLanguage.language ||
  604. // Couldn't determine language.
  605. null);
  606. }
  607. /**
  608. * @license
  609. * Copyright 2020 Google LLC
  610. *
  611. * Licensed under the Apache License, Version 2.0 (the "License");
  612. * you may not use this file except in compliance with the License.
  613. * You may obtain a copy of the License at
  614. *
  615. * http://www.apache.org/licenses/LICENSE-2.0
  616. *
  617. * Unless required by applicable law or agreed to in writing, software
  618. * distributed under the License is distributed on an "AS IS" BASIS,
  619. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  620. * See the License for the specific language governing permissions and
  621. * limitations under the License.
  622. */
  623. /**
  624. * A structure to help pick between a range of long and short delay durations
  625. * depending on the current environment. In general, the long delay is used for
  626. * mobile environments whereas short delays are used for desktop environments.
  627. */
  628. class Delay {
  629. constructor(shortDelay, longDelay) {
  630. this.shortDelay = shortDelay;
  631. this.longDelay = longDelay;
  632. // Internal error when improperly initialized.
  633. debugAssert(longDelay > shortDelay, 'Short delay should be less than long delay!');
  634. this.isMobile = util.isMobileCordova() || util.isReactNative();
  635. }
  636. get() {
  637. if (!_isOnline()) {
  638. // Pick the shorter timeout.
  639. return Math.min(5000 /* DelayMin.OFFLINE */, this.shortDelay);
  640. }
  641. // If running in a mobile environment, return the long delay, otherwise
  642. // return the short delay.
  643. // This could be improved in the future to dynamically change based on other
  644. // variables instead of just reading the current environment.
  645. return this.isMobile ? this.longDelay : this.shortDelay;
  646. }
  647. }
  648. /**
  649. * @license
  650. * Copyright 2020 Google LLC
  651. *
  652. * Licensed under the Apache License, Version 2.0 (the "License");
  653. * you may not use this file except in compliance with the License.
  654. * You may obtain a copy of the License at
  655. *
  656. * http://www.apache.org/licenses/LICENSE-2.0
  657. *
  658. * Unless required by applicable law or agreed to in writing, software
  659. * distributed under the License is distributed on an "AS IS" BASIS,
  660. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  661. * See the License for the specific language governing permissions and
  662. * limitations under the License.
  663. */
  664. function _emulatorUrl(config, path) {
  665. debugAssert(config.emulator, 'Emulator should always be set here');
  666. const { url } = config.emulator;
  667. if (!path) {
  668. return url;
  669. }
  670. return `${url}${path.startsWith('/') ? path.slice(1) : path}`;
  671. }
  672. /**
  673. * @license
  674. * Copyright 2020 Google LLC
  675. *
  676. * Licensed under the Apache License, Version 2.0 (the "License");
  677. * you may not use this file except in compliance with the License.
  678. * You may obtain a copy of the License at
  679. *
  680. * http://www.apache.org/licenses/LICENSE-2.0
  681. *
  682. * Unless required by applicable law or agreed to in writing, software
  683. * distributed under the License is distributed on an "AS IS" BASIS,
  684. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  685. * See the License for the specific language governing permissions and
  686. * limitations under the License.
  687. */
  688. class FetchProvider {
  689. static initialize(fetchImpl, headersImpl, responseImpl) {
  690. this.fetchImpl = fetchImpl;
  691. if (headersImpl) {
  692. this.headersImpl = headersImpl;
  693. }
  694. if (responseImpl) {
  695. this.responseImpl = responseImpl;
  696. }
  697. }
  698. static fetch() {
  699. if (this.fetchImpl) {
  700. return this.fetchImpl;
  701. }
  702. if (typeof self !== 'undefined' && 'fetch' in self) {
  703. return self.fetch;
  704. }
  705. debugFail('Could not find fetch implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill');
  706. }
  707. static headers() {
  708. if (this.headersImpl) {
  709. return this.headersImpl;
  710. }
  711. if (typeof self !== 'undefined' && 'Headers' in self) {
  712. return self.Headers;
  713. }
  714. debugFail('Could not find Headers implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill');
  715. }
  716. static response() {
  717. if (this.responseImpl) {
  718. return this.responseImpl;
  719. }
  720. if (typeof self !== 'undefined' && 'Response' in self) {
  721. return self.Response;
  722. }
  723. debugFail('Could not find Response implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill');
  724. }
  725. }
  726. /**
  727. * @license
  728. * Copyright 2020 Google LLC
  729. *
  730. * Licensed under the Apache License, Version 2.0 (the "License");
  731. * you may not use this file except in compliance with the License.
  732. * You may obtain a copy of the License at
  733. *
  734. * http://www.apache.org/licenses/LICENSE-2.0
  735. *
  736. * Unless required by applicable law or agreed to in writing, software
  737. * distributed under the License is distributed on an "AS IS" BASIS,
  738. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  739. * See the License for the specific language governing permissions and
  740. * limitations under the License.
  741. */
  742. /**
  743. * Map from errors returned by the server to errors to developer visible errors
  744. */
  745. const SERVER_ERROR_MAP = {
  746. // Custom token errors.
  747. ["CREDENTIAL_MISMATCH" /* ServerError.CREDENTIAL_MISMATCH */]: "custom-token-mismatch" /* AuthErrorCode.CREDENTIAL_MISMATCH */,
  748. // This can only happen if the SDK sends a bad request.
  749. ["MISSING_CUSTOM_TOKEN" /* ServerError.MISSING_CUSTOM_TOKEN */]: "internal-error" /* AuthErrorCode.INTERNAL_ERROR */,
  750. // Create Auth URI errors.
  751. ["INVALID_IDENTIFIER" /* ServerError.INVALID_IDENTIFIER */]: "invalid-email" /* AuthErrorCode.INVALID_EMAIL */,
  752. // This can only happen if the SDK sends a bad request.
  753. ["MISSING_CONTINUE_URI" /* ServerError.MISSING_CONTINUE_URI */]: "internal-error" /* AuthErrorCode.INTERNAL_ERROR */,
  754. // Sign in with email and password errors (some apply to sign up too).
  755. ["INVALID_PASSWORD" /* ServerError.INVALID_PASSWORD */]: "wrong-password" /* AuthErrorCode.INVALID_PASSWORD */,
  756. // This can only happen if the SDK sends a bad request.
  757. ["MISSING_PASSWORD" /* ServerError.MISSING_PASSWORD */]: "missing-password" /* AuthErrorCode.MISSING_PASSWORD */,
  758. // Sign up with email and password errors.
  759. ["EMAIL_EXISTS" /* ServerError.EMAIL_EXISTS */]: "email-already-in-use" /* AuthErrorCode.EMAIL_EXISTS */,
  760. ["PASSWORD_LOGIN_DISABLED" /* ServerError.PASSWORD_LOGIN_DISABLED */]: "operation-not-allowed" /* AuthErrorCode.OPERATION_NOT_ALLOWED */,
  761. // Verify assertion for sign in with credential errors:
  762. ["INVALID_IDP_RESPONSE" /* ServerError.INVALID_IDP_RESPONSE */]: "invalid-credential" /* AuthErrorCode.INVALID_IDP_RESPONSE */,
  763. ["INVALID_PENDING_TOKEN" /* ServerError.INVALID_PENDING_TOKEN */]: "invalid-credential" /* AuthErrorCode.INVALID_IDP_RESPONSE */,
  764. ["FEDERATED_USER_ID_ALREADY_LINKED" /* ServerError.FEDERATED_USER_ID_ALREADY_LINKED */]: "credential-already-in-use" /* AuthErrorCode.CREDENTIAL_ALREADY_IN_USE */,
  765. // This can only happen if the SDK sends a bad request.
  766. ["MISSING_REQ_TYPE" /* ServerError.MISSING_REQ_TYPE */]: "internal-error" /* AuthErrorCode.INTERNAL_ERROR */,
  767. // Send Password reset email errors:
  768. ["EMAIL_NOT_FOUND" /* ServerError.EMAIL_NOT_FOUND */]: "user-not-found" /* AuthErrorCode.USER_DELETED */,
  769. ["RESET_PASSWORD_EXCEED_LIMIT" /* ServerError.RESET_PASSWORD_EXCEED_LIMIT */]: "too-many-requests" /* AuthErrorCode.TOO_MANY_ATTEMPTS_TRY_LATER */,
  770. ["EXPIRED_OOB_CODE" /* ServerError.EXPIRED_OOB_CODE */]: "expired-action-code" /* AuthErrorCode.EXPIRED_OOB_CODE */,
  771. ["INVALID_OOB_CODE" /* ServerError.INVALID_OOB_CODE */]: "invalid-action-code" /* AuthErrorCode.INVALID_OOB_CODE */,
  772. // This can only happen if the SDK sends a bad request.
  773. ["MISSING_OOB_CODE" /* ServerError.MISSING_OOB_CODE */]: "internal-error" /* AuthErrorCode.INTERNAL_ERROR */,
  774. // Operations that require ID token in request:
  775. ["CREDENTIAL_TOO_OLD_LOGIN_AGAIN" /* ServerError.CREDENTIAL_TOO_OLD_LOGIN_AGAIN */]: "requires-recent-login" /* AuthErrorCode.CREDENTIAL_TOO_OLD_LOGIN_AGAIN */,
  776. ["INVALID_ID_TOKEN" /* ServerError.INVALID_ID_TOKEN */]: "invalid-user-token" /* AuthErrorCode.INVALID_AUTH */,
  777. ["TOKEN_EXPIRED" /* ServerError.TOKEN_EXPIRED */]: "user-token-expired" /* AuthErrorCode.TOKEN_EXPIRED */,
  778. ["USER_NOT_FOUND" /* ServerError.USER_NOT_FOUND */]: "user-token-expired" /* AuthErrorCode.TOKEN_EXPIRED */,
  779. // Other errors.
  780. ["TOO_MANY_ATTEMPTS_TRY_LATER" /* ServerError.TOO_MANY_ATTEMPTS_TRY_LATER */]: "too-many-requests" /* AuthErrorCode.TOO_MANY_ATTEMPTS_TRY_LATER */,
  781. // Phone Auth related errors.
  782. ["INVALID_CODE" /* ServerError.INVALID_CODE */]: "invalid-verification-code" /* AuthErrorCode.INVALID_CODE */,
  783. ["INVALID_SESSION_INFO" /* ServerError.INVALID_SESSION_INFO */]: "invalid-verification-id" /* AuthErrorCode.INVALID_SESSION_INFO */,
  784. ["INVALID_TEMPORARY_PROOF" /* ServerError.INVALID_TEMPORARY_PROOF */]: "invalid-credential" /* AuthErrorCode.INVALID_IDP_RESPONSE */,
  785. ["MISSING_SESSION_INFO" /* ServerError.MISSING_SESSION_INFO */]: "missing-verification-id" /* AuthErrorCode.MISSING_SESSION_INFO */,
  786. ["SESSION_EXPIRED" /* ServerError.SESSION_EXPIRED */]: "code-expired" /* AuthErrorCode.CODE_EXPIRED */,
  787. // Other action code errors when additional settings passed.
  788. // MISSING_CONTINUE_URI is getting mapped to INTERNAL_ERROR above.
  789. // This is OK as this error will be caught by client side validation.
  790. ["MISSING_ANDROID_PACKAGE_NAME" /* ServerError.MISSING_ANDROID_PACKAGE_NAME */]: "missing-android-pkg-name" /* AuthErrorCode.MISSING_ANDROID_PACKAGE_NAME */,
  791. ["UNAUTHORIZED_DOMAIN" /* ServerError.UNAUTHORIZED_DOMAIN */]: "unauthorized-continue-uri" /* AuthErrorCode.UNAUTHORIZED_DOMAIN */,
  792. // getProjectConfig errors when clientId is passed.
  793. ["INVALID_OAUTH_CLIENT_ID" /* ServerError.INVALID_OAUTH_CLIENT_ID */]: "invalid-oauth-client-id" /* AuthErrorCode.INVALID_OAUTH_CLIENT_ID */,
  794. // User actions (sign-up or deletion) disabled errors.
  795. ["ADMIN_ONLY_OPERATION" /* ServerError.ADMIN_ONLY_OPERATION */]: "admin-restricted-operation" /* AuthErrorCode.ADMIN_ONLY_OPERATION */,
  796. // Multi factor related errors.
  797. ["INVALID_MFA_PENDING_CREDENTIAL" /* ServerError.INVALID_MFA_PENDING_CREDENTIAL */]: "invalid-multi-factor-session" /* AuthErrorCode.INVALID_MFA_SESSION */,
  798. ["MFA_ENROLLMENT_NOT_FOUND" /* ServerError.MFA_ENROLLMENT_NOT_FOUND */]: "multi-factor-info-not-found" /* AuthErrorCode.MFA_INFO_NOT_FOUND */,
  799. ["MISSING_MFA_ENROLLMENT_ID" /* ServerError.MISSING_MFA_ENROLLMENT_ID */]: "missing-multi-factor-info" /* AuthErrorCode.MISSING_MFA_INFO */,
  800. ["MISSING_MFA_PENDING_CREDENTIAL" /* ServerError.MISSING_MFA_PENDING_CREDENTIAL */]: "missing-multi-factor-session" /* AuthErrorCode.MISSING_MFA_SESSION */,
  801. ["SECOND_FACTOR_EXISTS" /* ServerError.SECOND_FACTOR_EXISTS */]: "second-factor-already-in-use" /* AuthErrorCode.SECOND_FACTOR_ALREADY_ENROLLED */,
  802. ["SECOND_FACTOR_LIMIT_EXCEEDED" /* ServerError.SECOND_FACTOR_LIMIT_EXCEEDED */]: "maximum-second-factor-count-exceeded" /* AuthErrorCode.SECOND_FACTOR_LIMIT_EXCEEDED */,
  803. // Blocking functions related errors.
  804. ["BLOCKING_FUNCTION_ERROR_RESPONSE" /* ServerError.BLOCKING_FUNCTION_ERROR_RESPONSE */]: "internal-error" /* AuthErrorCode.INTERNAL_ERROR */,
  805. // Recaptcha related errors.
  806. ["RECAPTCHA_NOT_ENABLED" /* ServerError.RECAPTCHA_NOT_ENABLED */]: "recaptcha-not-enabled" /* AuthErrorCode.RECAPTCHA_NOT_ENABLED */,
  807. ["MISSING_RECAPTCHA_TOKEN" /* ServerError.MISSING_RECAPTCHA_TOKEN */]: "missing-recaptcha-token" /* AuthErrorCode.MISSING_RECAPTCHA_TOKEN */,
  808. ["INVALID_RECAPTCHA_TOKEN" /* ServerError.INVALID_RECAPTCHA_TOKEN */]: "invalid-recaptcha-token" /* AuthErrorCode.INVALID_RECAPTCHA_TOKEN */,
  809. ["INVALID_RECAPTCHA_ACTION" /* ServerError.INVALID_RECAPTCHA_ACTION */]: "invalid-recaptcha-action" /* AuthErrorCode.INVALID_RECAPTCHA_ACTION */,
  810. ["MISSING_CLIENT_TYPE" /* ServerError.MISSING_CLIENT_TYPE */]: "missing-client-type" /* AuthErrorCode.MISSING_CLIENT_TYPE */,
  811. ["MISSING_RECAPTCHA_VERSION" /* ServerError.MISSING_RECAPTCHA_VERSION */]: "missing-recaptcha-version" /* AuthErrorCode.MISSING_RECAPTCHA_VERSION */,
  812. ["INVALID_RECAPTCHA_VERSION" /* ServerError.INVALID_RECAPTCHA_VERSION */]: "invalid-recaptcha-version" /* AuthErrorCode.INVALID_RECAPTCHA_VERSION */,
  813. ["INVALID_REQ_TYPE" /* ServerError.INVALID_REQ_TYPE */]: "invalid-req-type" /* AuthErrorCode.INVALID_REQ_TYPE */
  814. };
  815. /**
  816. * @license
  817. * Copyright 2020 Google LLC
  818. *
  819. * Licensed under the Apache License, Version 2.0 (the "License");
  820. * you may not use this file except in compliance with the License.
  821. * You may obtain a copy of the License at
  822. *
  823. * http://www.apache.org/licenses/LICENSE-2.0
  824. *
  825. * Unless required by applicable law or agreed to in writing, software
  826. * distributed under the License is distributed on an "AS IS" BASIS,
  827. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  828. * See the License for the specific language governing permissions and
  829. * limitations under the License.
  830. */
  831. const DEFAULT_API_TIMEOUT_MS = new Delay(30000, 60000);
  832. function _addTidIfNecessary(auth, request) {
  833. if (auth.tenantId && !request.tenantId) {
  834. return Object.assign(Object.assign({}, request), { tenantId: auth.tenantId });
  835. }
  836. return request;
  837. }
  838. async function _performApiRequest(auth, method, path, request, customErrorMap = {}) {
  839. return _performFetchWithErrorHandling(auth, customErrorMap, async () => {
  840. let body = {};
  841. let params = {};
  842. if (request) {
  843. if (method === "GET" /* HttpMethod.GET */) {
  844. params = request;
  845. }
  846. else {
  847. body = {
  848. body: JSON.stringify(request)
  849. };
  850. }
  851. }
  852. const query = util.querystring(Object.assign({ key: auth.config.apiKey }, params)).slice(1);
  853. const headers = await auth._getAdditionalHeaders();
  854. headers["Content-Type" /* HttpHeader.CONTENT_TYPE */] = 'application/json';
  855. if (auth.languageCode) {
  856. headers["X-Firebase-Locale" /* HttpHeader.X_FIREBASE_LOCALE */] = auth.languageCode;
  857. }
  858. return FetchProvider.fetch()(_getFinalTarget(auth, auth.config.apiHost, path, query), Object.assign({ method,
  859. headers, referrerPolicy: 'no-referrer' }, body));
  860. });
  861. }
  862. async function _performFetchWithErrorHandling(auth, customErrorMap, fetchFn) {
  863. auth._canInitEmulator = false;
  864. const errorMap = Object.assign(Object.assign({}, SERVER_ERROR_MAP), customErrorMap);
  865. try {
  866. const networkTimeout = new NetworkTimeout(auth);
  867. const response = await Promise.race([
  868. fetchFn(),
  869. networkTimeout.promise
  870. ]);
  871. // If we've reached this point, the fetch succeeded and the networkTimeout
  872. // didn't throw; clear the network timeout delay so that Node won't hang
  873. networkTimeout.clearNetworkTimeout();
  874. const json = await response.json();
  875. if ('needConfirmation' in json) {
  876. throw _makeTaggedError(auth, "account-exists-with-different-credential" /* AuthErrorCode.NEED_CONFIRMATION */, json);
  877. }
  878. if (response.ok && !('errorMessage' in json)) {
  879. return json;
  880. }
  881. else {
  882. const errorMessage = response.ok ? json.errorMessage : json.error.message;
  883. const [serverErrorCode, serverErrorMessage] = errorMessage.split(' : ');
  884. if (serverErrorCode === "FEDERATED_USER_ID_ALREADY_LINKED" /* ServerError.FEDERATED_USER_ID_ALREADY_LINKED */) {
  885. throw _makeTaggedError(auth, "credential-already-in-use" /* AuthErrorCode.CREDENTIAL_ALREADY_IN_USE */, json);
  886. }
  887. else if (serverErrorCode === "EMAIL_EXISTS" /* ServerError.EMAIL_EXISTS */) {
  888. throw _makeTaggedError(auth, "email-already-in-use" /* AuthErrorCode.EMAIL_EXISTS */, json);
  889. }
  890. else if (serverErrorCode === "USER_DISABLED" /* ServerError.USER_DISABLED */) {
  891. throw _makeTaggedError(auth, "user-disabled" /* AuthErrorCode.USER_DISABLED */, json);
  892. }
  893. const authError = errorMap[serverErrorCode] ||
  894. serverErrorCode
  895. .toLowerCase()
  896. .replace(/[_\s]+/g, '-');
  897. if (serverErrorMessage) {
  898. throw _errorWithCustomMessage(auth, authError, serverErrorMessage);
  899. }
  900. else {
  901. _fail(auth, authError);
  902. }
  903. }
  904. }
  905. catch (e) {
  906. if (e instanceof util.FirebaseError) {
  907. throw e;
  908. }
  909. // Changing this to a different error code will log user out when there is a network error
  910. // because we treat any error other than NETWORK_REQUEST_FAILED as token is invalid.
  911. // https://github.com/firebase/firebase-js-sdk/blob/4fbc73610d70be4e0852e7de63a39cb7897e8546/packages/auth/src/core/auth/auth_impl.ts#L309-L316
  912. _fail(auth, "network-request-failed" /* AuthErrorCode.NETWORK_REQUEST_FAILED */, { 'message': String(e) });
  913. }
  914. }
  915. async function _performSignInRequest(auth, method, path, request, customErrorMap = {}) {
  916. const serverResponse = (await _performApiRequest(auth, method, path, request, customErrorMap));
  917. if ('mfaPendingCredential' in serverResponse) {
  918. _fail(auth, "multi-factor-auth-required" /* AuthErrorCode.MFA_REQUIRED */, {
  919. _serverResponse: serverResponse
  920. });
  921. }
  922. return serverResponse;
  923. }
  924. function _getFinalTarget(auth, host, path, query) {
  925. const base = `${host}${path}?${query}`;
  926. if (!auth.config.emulator) {
  927. return `${auth.config.apiScheme}://${base}`;
  928. }
  929. return _emulatorUrl(auth.config, base);
  930. }
  931. class NetworkTimeout {
  932. constructor(auth) {
  933. this.auth = auth;
  934. // Node timers and browser timers are fundamentally incompatible, but we
  935. // don't care about the value here
  936. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  937. this.timer = null;
  938. this.promise = new Promise((_, reject) => {
  939. this.timer = setTimeout(() => {
  940. return reject(_createError(this.auth, "network-request-failed" /* AuthErrorCode.NETWORK_REQUEST_FAILED */));
  941. }, DEFAULT_API_TIMEOUT_MS.get());
  942. });
  943. }
  944. clearNetworkTimeout() {
  945. clearTimeout(this.timer);
  946. }
  947. }
  948. function _makeTaggedError(auth, code, response) {
  949. const errorParams = {
  950. appName: auth.name
  951. };
  952. if (response.email) {
  953. errorParams.email = response.email;
  954. }
  955. if (response.phoneNumber) {
  956. errorParams.phoneNumber = response.phoneNumber;
  957. }
  958. const error = _createError(auth, code, errorParams);
  959. // We know customData is defined on error because errorParams is defined
  960. error.customData._tokenResponse = response;
  961. return error;
  962. }
  963. /**
  964. * @license
  965. * Copyright 2020 Google LLC
  966. *
  967. * Licensed under the Apache License, Version 2.0 (the "License");
  968. * you may not use this file except in compliance with the License.
  969. * You may obtain a copy of the License at
  970. *
  971. * http://www.apache.org/licenses/LICENSE-2.0
  972. *
  973. * Unless required by applicable law or agreed to in writing, software
  974. * distributed under the License is distributed on an "AS IS" BASIS,
  975. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  976. * See the License for the specific language governing permissions and
  977. * limitations under the License.
  978. */
  979. async function deleteAccount(auth, request) {
  980. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:delete" /* Endpoint.DELETE_ACCOUNT */, request);
  981. }
  982. async function deleteLinkedAccounts(auth, request) {
  983. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:update" /* Endpoint.SET_ACCOUNT_INFO */, request);
  984. }
  985. async function getAccountInfo(auth, request) {
  986. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:lookup" /* Endpoint.GET_ACCOUNT_INFO */, request);
  987. }
  988. /**
  989. * @license
  990. * Copyright 2020 Google LLC
  991. *
  992. * Licensed under the Apache License, Version 2.0 (the "License");
  993. * you may not use this file except in compliance with the License.
  994. * You may obtain a copy of the License at
  995. *
  996. * http://www.apache.org/licenses/LICENSE-2.0
  997. *
  998. * Unless required by applicable law or agreed to in writing, software
  999. * distributed under the License is distributed on an "AS IS" BASIS,
  1000. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1001. * See the License for the specific language governing permissions and
  1002. * limitations under the License.
  1003. */
  1004. function utcTimestampToDateString(utcTimestamp) {
  1005. if (!utcTimestamp) {
  1006. return undefined;
  1007. }
  1008. try {
  1009. // Convert to date object.
  1010. const date = new Date(Number(utcTimestamp));
  1011. // Test date is valid.
  1012. if (!isNaN(date.getTime())) {
  1013. // Convert to UTC date string.
  1014. return date.toUTCString();
  1015. }
  1016. }
  1017. catch (e) {
  1018. // Do nothing. undefined will be returned.
  1019. }
  1020. return undefined;
  1021. }
  1022. /**
  1023. * @license
  1024. * Copyright 2020 Google LLC
  1025. *
  1026. * Licensed under the Apache License, Version 2.0 (the "License");
  1027. * you may not use this file except in compliance with the License.
  1028. * You may obtain a copy of the License at
  1029. *
  1030. * http://www.apache.org/licenses/LICENSE-2.0
  1031. *
  1032. * Unless required by applicable law or agreed to in writing, software
  1033. * distributed under the License is distributed on an "AS IS" BASIS,
  1034. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1035. * See the License for the specific language governing permissions and
  1036. * limitations under the License.
  1037. */
  1038. /**
  1039. * Returns a JSON Web Token (JWT) used to identify the user to a Firebase service.
  1040. *
  1041. * @remarks
  1042. * Returns the current token if it has not expired or if it will not expire in the next five
  1043. * minutes. Otherwise, this will refresh the token and return a new one.
  1044. *
  1045. * @param user - The user.
  1046. * @param forceRefresh - Force refresh regardless of token expiration.
  1047. *
  1048. * @public
  1049. */
  1050. function getIdToken(user, forceRefresh = false) {
  1051. return util.getModularInstance(user).getIdToken(forceRefresh);
  1052. }
  1053. /**
  1054. * Returns a deserialized JSON Web Token (JWT) used to identify the user to a Firebase service.
  1055. *
  1056. * @remarks
  1057. * Returns the current token if it has not expired or if it will not expire in the next five
  1058. * minutes. Otherwise, this will refresh the token and return a new one.
  1059. *
  1060. * @param user - The user.
  1061. * @param forceRefresh - Force refresh regardless of token expiration.
  1062. *
  1063. * @public
  1064. */
  1065. async function getIdTokenResult(user, forceRefresh = false) {
  1066. const userInternal = util.getModularInstance(user);
  1067. const token = await userInternal.getIdToken(forceRefresh);
  1068. const claims = _parseToken(token);
  1069. _assert(claims && claims.exp && claims.auth_time && claims.iat, userInternal.auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  1070. const firebase = typeof claims.firebase === 'object' ? claims.firebase : undefined;
  1071. const signInProvider = firebase === null || firebase === void 0 ? void 0 : firebase['sign_in_provider'];
  1072. return {
  1073. claims,
  1074. token,
  1075. authTime: utcTimestampToDateString(secondsStringToMilliseconds(claims.auth_time)),
  1076. issuedAtTime: utcTimestampToDateString(secondsStringToMilliseconds(claims.iat)),
  1077. expirationTime: utcTimestampToDateString(secondsStringToMilliseconds(claims.exp)),
  1078. signInProvider: signInProvider || null,
  1079. signInSecondFactor: (firebase === null || firebase === void 0 ? void 0 : firebase['sign_in_second_factor']) || null
  1080. };
  1081. }
  1082. function secondsStringToMilliseconds(seconds) {
  1083. return Number(seconds) * 1000;
  1084. }
  1085. function _parseToken(token) {
  1086. const [algorithm, payload, signature] = token.split('.');
  1087. if (algorithm === undefined ||
  1088. payload === undefined ||
  1089. signature === undefined) {
  1090. _logError('JWT malformed, contained fewer than 3 sections');
  1091. return null;
  1092. }
  1093. try {
  1094. const decoded = util.base64Decode(payload);
  1095. if (!decoded) {
  1096. _logError('Failed to decode base64 JWT payload');
  1097. return null;
  1098. }
  1099. return JSON.parse(decoded);
  1100. }
  1101. catch (e) {
  1102. _logError('Caught error parsing JWT payload as JSON', e === null || e === void 0 ? void 0 : e.toString());
  1103. return null;
  1104. }
  1105. }
  1106. /**
  1107. * Extract expiresIn TTL from a token by subtracting the expiration from the issuance.
  1108. */
  1109. function _tokenExpiresIn(token) {
  1110. const parsedToken = _parseToken(token);
  1111. _assert(parsedToken, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  1112. _assert(typeof parsedToken.exp !== 'undefined', "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  1113. _assert(typeof parsedToken.iat !== 'undefined', "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  1114. return Number(parsedToken.exp) - Number(parsedToken.iat);
  1115. }
  1116. /**
  1117. * @license
  1118. * Copyright 2020 Google LLC
  1119. *
  1120. * Licensed under the Apache License, Version 2.0 (the "License");
  1121. * you may not use this file except in compliance with the License.
  1122. * You may obtain a copy of the License at
  1123. *
  1124. * http://www.apache.org/licenses/LICENSE-2.0
  1125. *
  1126. * Unless required by applicable law or agreed to in writing, software
  1127. * distributed under the License is distributed on an "AS IS" BASIS,
  1128. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1129. * See the License for the specific language governing permissions and
  1130. * limitations under the License.
  1131. */
  1132. async function _logoutIfInvalidated(user, promise, bypassAuthState = false) {
  1133. if (bypassAuthState) {
  1134. return promise;
  1135. }
  1136. try {
  1137. return await promise;
  1138. }
  1139. catch (e) {
  1140. if (e instanceof util.FirebaseError && isUserInvalidated(e)) {
  1141. if (user.auth.currentUser === user) {
  1142. await user.auth.signOut();
  1143. }
  1144. }
  1145. throw e;
  1146. }
  1147. }
  1148. function isUserInvalidated({ code }) {
  1149. return (code === `auth/${"user-disabled" /* AuthErrorCode.USER_DISABLED */}` ||
  1150. code === `auth/${"user-token-expired" /* AuthErrorCode.TOKEN_EXPIRED */}`);
  1151. }
  1152. /**
  1153. * @license
  1154. * Copyright 2020 Google LLC
  1155. *
  1156. * Licensed under the Apache License, Version 2.0 (the "License");
  1157. * you may not use this file except in compliance with the License.
  1158. * You may obtain a copy of the License at
  1159. *
  1160. * http://www.apache.org/licenses/LICENSE-2.0
  1161. *
  1162. * Unless required by applicable law or agreed to in writing, software
  1163. * distributed under the License is distributed on an "AS IS" BASIS,
  1164. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1165. * See the License for the specific language governing permissions and
  1166. * limitations under the License.
  1167. */
  1168. class ProactiveRefresh {
  1169. constructor(user) {
  1170. this.user = user;
  1171. this.isRunning = false;
  1172. // Node timers and browser timers return fundamentally different types.
  1173. // We don't actually care what the value is but TS won't accept unknown and
  1174. // we can't cast properly in both environments.
  1175. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1176. this.timerId = null;
  1177. this.errorBackoff = 30000 /* Duration.RETRY_BACKOFF_MIN */;
  1178. }
  1179. _start() {
  1180. if (this.isRunning) {
  1181. return;
  1182. }
  1183. this.isRunning = true;
  1184. this.schedule();
  1185. }
  1186. _stop() {
  1187. if (!this.isRunning) {
  1188. return;
  1189. }
  1190. this.isRunning = false;
  1191. if (this.timerId !== null) {
  1192. clearTimeout(this.timerId);
  1193. }
  1194. }
  1195. getInterval(wasError) {
  1196. var _a;
  1197. if (wasError) {
  1198. const interval = this.errorBackoff;
  1199. this.errorBackoff = Math.min(this.errorBackoff * 2, 960000 /* Duration.RETRY_BACKOFF_MAX */);
  1200. return interval;
  1201. }
  1202. else {
  1203. // Reset the error backoff
  1204. this.errorBackoff = 30000 /* Duration.RETRY_BACKOFF_MIN */;
  1205. const expTime = (_a = this.user.stsTokenManager.expirationTime) !== null && _a !== void 0 ? _a : 0;
  1206. const interval = expTime - Date.now() - 300000 /* Duration.OFFSET */;
  1207. return Math.max(0, interval);
  1208. }
  1209. }
  1210. schedule(wasError = false) {
  1211. if (!this.isRunning) {
  1212. // Just in case...
  1213. return;
  1214. }
  1215. const interval = this.getInterval(wasError);
  1216. this.timerId = setTimeout(async () => {
  1217. await this.iteration();
  1218. }, interval);
  1219. }
  1220. async iteration() {
  1221. try {
  1222. await this.user.getIdToken(true);
  1223. }
  1224. catch (e) {
  1225. // Only retry on network errors
  1226. if ((e === null || e === void 0 ? void 0 : e.code) ===
  1227. `auth/${"network-request-failed" /* AuthErrorCode.NETWORK_REQUEST_FAILED */}`) {
  1228. this.schedule(/* wasError */ true);
  1229. }
  1230. return;
  1231. }
  1232. this.schedule();
  1233. }
  1234. }
  1235. /**
  1236. * @license
  1237. * Copyright 2020 Google LLC
  1238. *
  1239. * Licensed under the Apache License, Version 2.0 (the "License");
  1240. * you may not use this file except in compliance with the License.
  1241. * You may obtain a copy of the License at
  1242. *
  1243. * http://www.apache.org/licenses/LICENSE-2.0
  1244. *
  1245. * Unless required by applicable law or agreed to in writing, software
  1246. * distributed under the License is distributed on an "AS IS" BASIS,
  1247. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1248. * See the License for the specific language governing permissions and
  1249. * limitations under the License.
  1250. */
  1251. class UserMetadata {
  1252. constructor(createdAt, lastLoginAt) {
  1253. this.createdAt = createdAt;
  1254. this.lastLoginAt = lastLoginAt;
  1255. this._initializeTime();
  1256. }
  1257. _initializeTime() {
  1258. this.lastSignInTime = utcTimestampToDateString(this.lastLoginAt);
  1259. this.creationTime = utcTimestampToDateString(this.createdAt);
  1260. }
  1261. _copy(metadata) {
  1262. this.createdAt = metadata.createdAt;
  1263. this.lastLoginAt = metadata.lastLoginAt;
  1264. this._initializeTime();
  1265. }
  1266. toJSON() {
  1267. return {
  1268. createdAt: this.createdAt,
  1269. lastLoginAt: this.lastLoginAt
  1270. };
  1271. }
  1272. }
  1273. /**
  1274. * @license
  1275. * Copyright 2019 Google LLC
  1276. *
  1277. * Licensed under the Apache License, Version 2.0 (the "License");
  1278. * you may not use this file except in compliance with the License.
  1279. * You may obtain a copy of the License at
  1280. *
  1281. * http://www.apache.org/licenses/LICENSE-2.0
  1282. *
  1283. * Unless required by applicable law or agreed to in writing, software
  1284. * distributed under the License is distributed on an "AS IS" BASIS,
  1285. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1286. * See the License for the specific language governing permissions and
  1287. * limitations under the License.
  1288. */
  1289. async function _reloadWithoutSaving(user) {
  1290. var _a;
  1291. const auth = user.auth;
  1292. const idToken = await user.getIdToken();
  1293. const response = await _logoutIfInvalidated(user, getAccountInfo(auth, { idToken }));
  1294. _assert(response === null || response === void 0 ? void 0 : response.users.length, auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  1295. const coreAccount = response.users[0];
  1296. user._notifyReloadListener(coreAccount);
  1297. const newProviderData = ((_a = coreAccount.providerUserInfo) === null || _a === void 0 ? void 0 : _a.length)
  1298. ? extractProviderData(coreAccount.providerUserInfo)
  1299. : [];
  1300. const providerData = mergeProviderData(user.providerData, newProviderData);
  1301. // Preserves the non-nonymous status of the stored user, even if no more
  1302. // credentials (federated or email/password) are linked to the user. If
  1303. // the user was previously anonymous, then use provider data to update.
  1304. // On the other hand, if it was not anonymous before, it should never be
  1305. // considered anonymous now.
  1306. const oldIsAnonymous = user.isAnonymous;
  1307. const newIsAnonymous = !(user.email && coreAccount.passwordHash) && !(providerData === null || providerData === void 0 ? void 0 : providerData.length);
  1308. const isAnonymous = !oldIsAnonymous ? false : newIsAnonymous;
  1309. const updates = {
  1310. uid: coreAccount.localId,
  1311. displayName: coreAccount.displayName || null,
  1312. photoURL: coreAccount.photoUrl || null,
  1313. email: coreAccount.email || null,
  1314. emailVerified: coreAccount.emailVerified || false,
  1315. phoneNumber: coreAccount.phoneNumber || null,
  1316. tenantId: coreAccount.tenantId || null,
  1317. providerData,
  1318. metadata: new UserMetadata(coreAccount.createdAt, coreAccount.lastLoginAt),
  1319. isAnonymous
  1320. };
  1321. Object.assign(user, updates);
  1322. }
  1323. /**
  1324. * Reloads user account data, if signed in.
  1325. *
  1326. * @param user - The user.
  1327. *
  1328. * @public
  1329. */
  1330. async function reload(user) {
  1331. const userInternal = util.getModularInstance(user);
  1332. await _reloadWithoutSaving(userInternal);
  1333. // Even though the current user hasn't changed, update
  1334. // current user will trigger a persistence update w/ the
  1335. // new info.
  1336. await userInternal.auth._persistUserIfCurrent(userInternal);
  1337. userInternal.auth._notifyListenersIfCurrent(userInternal);
  1338. }
  1339. function mergeProviderData(original, newData) {
  1340. const deduped = original.filter(o => !newData.some(n => n.providerId === o.providerId));
  1341. return [...deduped, ...newData];
  1342. }
  1343. function extractProviderData(providers) {
  1344. return providers.map((_a) => {
  1345. var { providerId } = _a, provider = tslib.__rest(_a, ["providerId"]);
  1346. return {
  1347. providerId,
  1348. uid: provider.rawId || '',
  1349. displayName: provider.displayName || null,
  1350. email: provider.email || null,
  1351. phoneNumber: provider.phoneNumber || null,
  1352. photoURL: provider.photoUrl || null
  1353. };
  1354. });
  1355. }
  1356. /**
  1357. * @license
  1358. * Copyright 2020 Google LLC
  1359. *
  1360. * Licensed under the Apache License, Version 2.0 (the "License");
  1361. * you may not use this file except in compliance with the License.
  1362. * You may obtain a copy of the License at
  1363. *
  1364. * http://www.apache.org/licenses/LICENSE-2.0
  1365. *
  1366. * Unless required by applicable law or agreed to in writing, software
  1367. * distributed under the License is distributed on an "AS IS" BASIS,
  1368. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1369. * See the License for the specific language governing permissions and
  1370. * limitations under the License.
  1371. */
  1372. async function requestStsToken(auth, refreshToken) {
  1373. const response = await _performFetchWithErrorHandling(auth, {}, async () => {
  1374. const body = util.querystring({
  1375. 'grant_type': 'refresh_token',
  1376. 'refresh_token': refreshToken
  1377. }).slice(1);
  1378. const { tokenApiHost, apiKey } = auth.config;
  1379. const url = _getFinalTarget(auth, tokenApiHost, "/v1/token" /* Endpoint.TOKEN */, `key=${apiKey}`);
  1380. const headers = await auth._getAdditionalHeaders();
  1381. headers["Content-Type" /* HttpHeader.CONTENT_TYPE */] = 'application/x-www-form-urlencoded';
  1382. return FetchProvider.fetch()(url, {
  1383. method: "POST" /* HttpMethod.POST */,
  1384. headers,
  1385. body
  1386. });
  1387. });
  1388. // The response comes back in snake_case. Convert to camel:
  1389. return {
  1390. accessToken: response.access_token,
  1391. expiresIn: response.expires_in,
  1392. refreshToken: response.refresh_token
  1393. };
  1394. }
  1395. /**
  1396. * @license
  1397. * Copyright 2020 Google LLC
  1398. *
  1399. * Licensed under the Apache License, Version 2.0 (the "License");
  1400. * you may not use this file except in compliance with the License.
  1401. * You may obtain a copy of the License at
  1402. *
  1403. * http://www.apache.org/licenses/LICENSE-2.0
  1404. *
  1405. * Unless required by applicable law or agreed to in writing, software
  1406. * distributed under the License is distributed on an "AS IS" BASIS,
  1407. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1408. * See the License for the specific language governing permissions and
  1409. * limitations under the License.
  1410. */
  1411. /**
  1412. * We need to mark this class as internal explicitly to exclude it in the public typings, because
  1413. * it references AuthInternal which has a circular dependency with UserInternal.
  1414. *
  1415. * @internal
  1416. */
  1417. class StsTokenManager {
  1418. constructor() {
  1419. this.refreshToken = null;
  1420. this.accessToken = null;
  1421. this.expirationTime = null;
  1422. }
  1423. get isExpired() {
  1424. return (!this.expirationTime ||
  1425. Date.now() > this.expirationTime - 30000 /* Buffer.TOKEN_REFRESH */);
  1426. }
  1427. updateFromServerResponse(response) {
  1428. _assert(response.idToken, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  1429. _assert(typeof response.idToken !== 'undefined', "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  1430. _assert(typeof response.refreshToken !== 'undefined', "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  1431. const expiresIn = 'expiresIn' in response && typeof response.expiresIn !== 'undefined'
  1432. ? Number(response.expiresIn)
  1433. : _tokenExpiresIn(response.idToken);
  1434. this.updateTokensAndExpiration(response.idToken, response.refreshToken, expiresIn);
  1435. }
  1436. async getToken(auth, forceRefresh = false) {
  1437. _assert(!this.accessToken || this.refreshToken, auth, "user-token-expired" /* AuthErrorCode.TOKEN_EXPIRED */);
  1438. if (!forceRefresh && this.accessToken && !this.isExpired) {
  1439. return this.accessToken;
  1440. }
  1441. if (this.refreshToken) {
  1442. await this.refresh(auth, this.refreshToken);
  1443. return this.accessToken;
  1444. }
  1445. return null;
  1446. }
  1447. clearRefreshToken() {
  1448. this.refreshToken = null;
  1449. }
  1450. async refresh(auth, oldToken) {
  1451. const { accessToken, refreshToken, expiresIn } = await requestStsToken(auth, oldToken);
  1452. this.updateTokensAndExpiration(accessToken, refreshToken, Number(expiresIn));
  1453. }
  1454. updateTokensAndExpiration(accessToken, refreshToken, expiresInSec) {
  1455. this.refreshToken = refreshToken || null;
  1456. this.accessToken = accessToken || null;
  1457. this.expirationTime = Date.now() + expiresInSec * 1000;
  1458. }
  1459. static fromJSON(appName, object) {
  1460. const { refreshToken, accessToken, expirationTime } = object;
  1461. const manager = new StsTokenManager();
  1462. if (refreshToken) {
  1463. _assert(typeof refreshToken === 'string', "internal-error" /* AuthErrorCode.INTERNAL_ERROR */, {
  1464. appName
  1465. });
  1466. manager.refreshToken = refreshToken;
  1467. }
  1468. if (accessToken) {
  1469. _assert(typeof accessToken === 'string', "internal-error" /* AuthErrorCode.INTERNAL_ERROR */, {
  1470. appName
  1471. });
  1472. manager.accessToken = accessToken;
  1473. }
  1474. if (expirationTime) {
  1475. _assert(typeof expirationTime === 'number', "internal-error" /* AuthErrorCode.INTERNAL_ERROR */, {
  1476. appName
  1477. });
  1478. manager.expirationTime = expirationTime;
  1479. }
  1480. return manager;
  1481. }
  1482. toJSON() {
  1483. return {
  1484. refreshToken: this.refreshToken,
  1485. accessToken: this.accessToken,
  1486. expirationTime: this.expirationTime
  1487. };
  1488. }
  1489. _assign(stsTokenManager) {
  1490. this.accessToken = stsTokenManager.accessToken;
  1491. this.refreshToken = stsTokenManager.refreshToken;
  1492. this.expirationTime = stsTokenManager.expirationTime;
  1493. }
  1494. _clone() {
  1495. return Object.assign(new StsTokenManager(), this.toJSON());
  1496. }
  1497. _performRefresh() {
  1498. return debugFail('not implemented');
  1499. }
  1500. }
  1501. /**
  1502. * @license
  1503. * Copyright 2020 Google LLC
  1504. *
  1505. * Licensed under the Apache License, Version 2.0 (the "License");
  1506. * you may not use this file except in compliance with the License.
  1507. * You may obtain a copy of the License at
  1508. *
  1509. * http://www.apache.org/licenses/LICENSE-2.0
  1510. *
  1511. * Unless required by applicable law or agreed to in writing, software
  1512. * distributed under the License is distributed on an "AS IS" BASIS,
  1513. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1514. * See the License for the specific language governing permissions and
  1515. * limitations under the License.
  1516. */
  1517. function assertStringOrUndefined(assertion, appName) {
  1518. _assert(typeof assertion === 'string' || typeof assertion === 'undefined', "internal-error" /* AuthErrorCode.INTERNAL_ERROR */, { appName });
  1519. }
  1520. class UserImpl {
  1521. constructor(_a) {
  1522. var { uid, auth, stsTokenManager } = _a, opt = tslib.__rest(_a, ["uid", "auth", "stsTokenManager"]);
  1523. // For the user object, provider is always Firebase.
  1524. this.providerId = "firebase" /* ProviderId.FIREBASE */;
  1525. this.proactiveRefresh = new ProactiveRefresh(this);
  1526. this.reloadUserInfo = null;
  1527. this.reloadListener = null;
  1528. this.uid = uid;
  1529. this.auth = auth;
  1530. this.stsTokenManager = stsTokenManager;
  1531. this.accessToken = stsTokenManager.accessToken;
  1532. this.displayName = opt.displayName || null;
  1533. this.email = opt.email || null;
  1534. this.emailVerified = opt.emailVerified || false;
  1535. this.phoneNumber = opt.phoneNumber || null;
  1536. this.photoURL = opt.photoURL || null;
  1537. this.isAnonymous = opt.isAnonymous || false;
  1538. this.tenantId = opt.tenantId || null;
  1539. this.providerData = opt.providerData ? [...opt.providerData] : [];
  1540. this.metadata = new UserMetadata(opt.createdAt || undefined, opt.lastLoginAt || undefined);
  1541. }
  1542. async getIdToken(forceRefresh) {
  1543. const accessToken = await _logoutIfInvalidated(this, this.stsTokenManager.getToken(this.auth, forceRefresh));
  1544. _assert(accessToken, this.auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  1545. if (this.accessToken !== accessToken) {
  1546. this.accessToken = accessToken;
  1547. await this.auth._persistUserIfCurrent(this);
  1548. this.auth._notifyListenersIfCurrent(this);
  1549. }
  1550. return accessToken;
  1551. }
  1552. getIdTokenResult(forceRefresh) {
  1553. return getIdTokenResult(this, forceRefresh);
  1554. }
  1555. reload() {
  1556. return reload(this);
  1557. }
  1558. _assign(user) {
  1559. if (this === user) {
  1560. return;
  1561. }
  1562. _assert(this.uid === user.uid, this.auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  1563. this.displayName = user.displayName;
  1564. this.photoURL = user.photoURL;
  1565. this.email = user.email;
  1566. this.emailVerified = user.emailVerified;
  1567. this.phoneNumber = user.phoneNumber;
  1568. this.isAnonymous = user.isAnonymous;
  1569. this.tenantId = user.tenantId;
  1570. this.providerData = user.providerData.map(userInfo => (Object.assign({}, userInfo)));
  1571. this.metadata._copy(user.metadata);
  1572. this.stsTokenManager._assign(user.stsTokenManager);
  1573. }
  1574. _clone(auth) {
  1575. const newUser = new UserImpl(Object.assign(Object.assign({}, this), { auth, stsTokenManager: this.stsTokenManager._clone() }));
  1576. newUser.metadata._copy(this.metadata);
  1577. return newUser;
  1578. }
  1579. _onReload(callback) {
  1580. // There should only ever be one listener, and that is a single instance of MultiFactorUser
  1581. _assert(!this.reloadListener, this.auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  1582. this.reloadListener = callback;
  1583. if (this.reloadUserInfo) {
  1584. this._notifyReloadListener(this.reloadUserInfo);
  1585. this.reloadUserInfo = null;
  1586. }
  1587. }
  1588. _notifyReloadListener(userInfo) {
  1589. if (this.reloadListener) {
  1590. this.reloadListener(userInfo);
  1591. }
  1592. else {
  1593. // If no listener is subscribed yet, save the result so it's available when they do subscribe
  1594. this.reloadUserInfo = userInfo;
  1595. }
  1596. }
  1597. _startProactiveRefresh() {
  1598. this.proactiveRefresh._start();
  1599. }
  1600. _stopProactiveRefresh() {
  1601. this.proactiveRefresh._stop();
  1602. }
  1603. async _updateTokensIfNecessary(response, reload = false) {
  1604. let tokensRefreshed = false;
  1605. if (response.idToken &&
  1606. response.idToken !== this.stsTokenManager.accessToken) {
  1607. this.stsTokenManager.updateFromServerResponse(response);
  1608. tokensRefreshed = true;
  1609. }
  1610. if (reload) {
  1611. await _reloadWithoutSaving(this);
  1612. }
  1613. await this.auth._persistUserIfCurrent(this);
  1614. if (tokensRefreshed) {
  1615. this.auth._notifyListenersIfCurrent(this);
  1616. }
  1617. }
  1618. async delete() {
  1619. const idToken = await this.getIdToken();
  1620. await _logoutIfInvalidated(this, deleteAccount(this.auth, { idToken }));
  1621. this.stsTokenManager.clearRefreshToken();
  1622. // TODO: Determine if cancellable-promises are necessary to use in this class so that delete()
  1623. // cancels pending actions...
  1624. return this.auth.signOut();
  1625. }
  1626. toJSON() {
  1627. return Object.assign(Object.assign({ uid: this.uid, email: this.email || undefined, emailVerified: this.emailVerified, displayName: this.displayName || undefined, isAnonymous: this.isAnonymous, photoURL: this.photoURL || undefined, phoneNumber: this.phoneNumber || undefined, tenantId: this.tenantId || undefined, providerData: this.providerData.map(userInfo => (Object.assign({}, userInfo))), stsTokenManager: this.stsTokenManager.toJSON(),
  1628. // Redirect event ID must be maintained in case there is a pending
  1629. // redirect event.
  1630. _redirectEventId: this._redirectEventId }, this.metadata.toJSON()), {
  1631. // Required for compatibility with the legacy SDK (go/firebase-auth-sdk-persistence-parsing):
  1632. apiKey: this.auth.config.apiKey, appName: this.auth.name });
  1633. }
  1634. get refreshToken() {
  1635. return this.stsTokenManager.refreshToken || '';
  1636. }
  1637. static _fromJSON(auth, object) {
  1638. var _a, _b, _c, _d, _e, _f, _g, _h;
  1639. const displayName = (_a = object.displayName) !== null && _a !== void 0 ? _a : undefined;
  1640. const email = (_b = object.email) !== null && _b !== void 0 ? _b : undefined;
  1641. const phoneNumber = (_c = object.phoneNumber) !== null && _c !== void 0 ? _c : undefined;
  1642. const photoURL = (_d = object.photoURL) !== null && _d !== void 0 ? _d : undefined;
  1643. const tenantId = (_e = object.tenantId) !== null && _e !== void 0 ? _e : undefined;
  1644. const _redirectEventId = (_f = object._redirectEventId) !== null && _f !== void 0 ? _f : undefined;
  1645. const createdAt = (_g = object.createdAt) !== null && _g !== void 0 ? _g : undefined;
  1646. const lastLoginAt = (_h = object.lastLoginAt) !== null && _h !== void 0 ? _h : undefined;
  1647. const { uid, emailVerified, isAnonymous, providerData, stsTokenManager: plainObjectTokenManager } = object;
  1648. _assert(uid && plainObjectTokenManager, auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  1649. const stsTokenManager = StsTokenManager.fromJSON(this.name, plainObjectTokenManager);
  1650. _assert(typeof uid === 'string', auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  1651. assertStringOrUndefined(displayName, auth.name);
  1652. assertStringOrUndefined(email, auth.name);
  1653. _assert(typeof emailVerified === 'boolean', auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  1654. _assert(typeof isAnonymous === 'boolean', auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  1655. assertStringOrUndefined(phoneNumber, auth.name);
  1656. assertStringOrUndefined(photoURL, auth.name);
  1657. assertStringOrUndefined(tenantId, auth.name);
  1658. assertStringOrUndefined(_redirectEventId, auth.name);
  1659. assertStringOrUndefined(createdAt, auth.name);
  1660. assertStringOrUndefined(lastLoginAt, auth.name);
  1661. const user = new UserImpl({
  1662. uid,
  1663. auth,
  1664. email,
  1665. emailVerified,
  1666. displayName,
  1667. isAnonymous,
  1668. photoURL,
  1669. phoneNumber,
  1670. tenantId,
  1671. stsTokenManager,
  1672. createdAt,
  1673. lastLoginAt
  1674. });
  1675. if (providerData && Array.isArray(providerData)) {
  1676. user.providerData = providerData.map(userInfo => (Object.assign({}, userInfo)));
  1677. }
  1678. if (_redirectEventId) {
  1679. user._redirectEventId = _redirectEventId;
  1680. }
  1681. return user;
  1682. }
  1683. /**
  1684. * Initialize a User from an idToken server response
  1685. * @param auth
  1686. * @param idTokenResponse
  1687. */
  1688. static async _fromIdTokenResponse(auth, idTokenResponse, isAnonymous = false) {
  1689. const stsTokenManager = new StsTokenManager();
  1690. stsTokenManager.updateFromServerResponse(idTokenResponse);
  1691. // Initialize the Firebase Auth user.
  1692. const user = new UserImpl({
  1693. uid: idTokenResponse.localId,
  1694. auth,
  1695. stsTokenManager,
  1696. isAnonymous
  1697. });
  1698. // Updates the user info and data and resolves with a user instance.
  1699. await _reloadWithoutSaving(user);
  1700. return user;
  1701. }
  1702. }
  1703. /**
  1704. * @license
  1705. * Copyright 2020 Google LLC
  1706. *
  1707. * Licensed under the Apache License, Version 2.0 (the "License");
  1708. * you may not use this file except in compliance with the License.
  1709. * You may obtain a copy of the License at
  1710. *
  1711. * http://www.apache.org/licenses/LICENSE-2.0
  1712. *
  1713. * Unless required by applicable law or agreed to in writing, software
  1714. * distributed under the License is distributed on an "AS IS" BASIS,
  1715. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1716. * See the License for the specific language governing permissions and
  1717. * limitations under the License.
  1718. */
  1719. const instanceCache = new Map();
  1720. function _getInstance(cls) {
  1721. debugAssert(cls instanceof Function, 'Expected a class definition');
  1722. let instance = instanceCache.get(cls);
  1723. if (instance) {
  1724. debugAssert(instance instanceof cls, 'Instance stored in cache mismatched with class');
  1725. return instance;
  1726. }
  1727. instance = new cls();
  1728. instanceCache.set(cls, instance);
  1729. return instance;
  1730. }
  1731. /**
  1732. * @license
  1733. * Copyright 2019 Google LLC
  1734. *
  1735. * Licensed under the Apache License, Version 2.0 (the "License");
  1736. * you may not use this file except in compliance with the License.
  1737. * You may obtain a copy of the License at
  1738. *
  1739. * http://www.apache.org/licenses/LICENSE-2.0
  1740. *
  1741. * Unless required by applicable law or agreed to in writing, software
  1742. * distributed under the License is distributed on an "AS IS" BASIS,
  1743. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1744. * See the License for the specific language governing permissions and
  1745. * limitations under the License.
  1746. */
  1747. class InMemoryPersistence {
  1748. constructor() {
  1749. this.type = "NONE" /* PersistenceType.NONE */;
  1750. this.storage = {};
  1751. }
  1752. async _isAvailable() {
  1753. return true;
  1754. }
  1755. async _set(key, value) {
  1756. this.storage[key] = value;
  1757. }
  1758. async _get(key) {
  1759. const value = this.storage[key];
  1760. return value === undefined ? null : value;
  1761. }
  1762. async _remove(key) {
  1763. delete this.storage[key];
  1764. }
  1765. _addListener(_key, _listener) {
  1766. // Listeners are not supported for in-memory storage since it cannot be shared across windows/workers
  1767. return;
  1768. }
  1769. _removeListener(_key, _listener) {
  1770. // Listeners are not supported for in-memory storage since it cannot be shared across windows/workers
  1771. return;
  1772. }
  1773. }
  1774. InMemoryPersistence.type = 'NONE';
  1775. /**
  1776. * An implementation of {@link Persistence} of type 'NONE'.
  1777. *
  1778. * @public
  1779. */
  1780. const inMemoryPersistence = InMemoryPersistence;
  1781. /**
  1782. * @license
  1783. * Copyright 2019 Google LLC
  1784. *
  1785. * Licensed under the Apache License, Version 2.0 (the "License");
  1786. * you may not use this file except in compliance with the License.
  1787. * You may obtain a copy of the License at
  1788. *
  1789. * http://www.apache.org/licenses/LICENSE-2.0
  1790. *
  1791. * Unless required by applicable law or agreed to in writing, software
  1792. * distributed under the License is distributed on an "AS IS" BASIS,
  1793. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1794. * See the License for the specific language governing permissions and
  1795. * limitations under the License.
  1796. */
  1797. function _persistenceKeyName(key, apiKey, appName) {
  1798. return `${"firebase" /* Namespace.PERSISTENCE */}:${key}:${apiKey}:${appName}`;
  1799. }
  1800. class PersistenceUserManager {
  1801. constructor(persistence, auth, userKey) {
  1802. this.persistence = persistence;
  1803. this.auth = auth;
  1804. this.userKey = userKey;
  1805. const { config, name } = this.auth;
  1806. this.fullUserKey = _persistenceKeyName(this.userKey, config.apiKey, name);
  1807. this.fullPersistenceKey = _persistenceKeyName("persistence" /* KeyName.PERSISTENCE_USER */, config.apiKey, name);
  1808. this.boundEventHandler = auth._onStorageEvent.bind(auth);
  1809. this.persistence._addListener(this.fullUserKey, this.boundEventHandler);
  1810. }
  1811. setCurrentUser(user) {
  1812. return this.persistence._set(this.fullUserKey, user.toJSON());
  1813. }
  1814. async getCurrentUser() {
  1815. const blob = await this.persistence._get(this.fullUserKey);
  1816. return blob ? UserImpl._fromJSON(this.auth, blob) : null;
  1817. }
  1818. removeCurrentUser() {
  1819. return this.persistence._remove(this.fullUserKey);
  1820. }
  1821. savePersistenceForRedirect() {
  1822. return this.persistence._set(this.fullPersistenceKey, this.persistence.type);
  1823. }
  1824. async setPersistence(newPersistence) {
  1825. if (this.persistence === newPersistence) {
  1826. return;
  1827. }
  1828. const currentUser = await this.getCurrentUser();
  1829. await this.removeCurrentUser();
  1830. this.persistence = newPersistence;
  1831. if (currentUser) {
  1832. return this.setCurrentUser(currentUser);
  1833. }
  1834. }
  1835. delete() {
  1836. this.persistence._removeListener(this.fullUserKey, this.boundEventHandler);
  1837. }
  1838. static async create(auth, persistenceHierarchy, userKey = "authUser" /* KeyName.AUTH_USER */) {
  1839. if (!persistenceHierarchy.length) {
  1840. return new PersistenceUserManager(_getInstance(inMemoryPersistence), auth, userKey);
  1841. }
  1842. // Eliminate any persistences that are not available
  1843. const availablePersistences = (await Promise.all(persistenceHierarchy.map(async (persistence) => {
  1844. if (await persistence._isAvailable()) {
  1845. return persistence;
  1846. }
  1847. return undefined;
  1848. }))).filter(persistence => persistence);
  1849. // Fall back to the first persistence listed, or in memory if none available
  1850. let selectedPersistence = availablePersistences[0] ||
  1851. _getInstance(inMemoryPersistence);
  1852. const key = _persistenceKeyName(userKey, auth.config.apiKey, auth.name);
  1853. // Pull out the existing user, setting the chosen persistence to that
  1854. // persistence if the user exists.
  1855. let userToMigrate = null;
  1856. // Note, here we check for a user in _all_ persistences, not just the
  1857. // ones deemed available. If we can migrate a user out of a broken
  1858. // persistence, we will (but only if that persistence supports migration).
  1859. for (const persistence of persistenceHierarchy) {
  1860. try {
  1861. const blob = await persistence._get(key);
  1862. if (blob) {
  1863. const user = UserImpl._fromJSON(auth, blob); // throws for unparsable blob (wrong format)
  1864. if (persistence !== selectedPersistence) {
  1865. userToMigrate = user;
  1866. }
  1867. selectedPersistence = persistence;
  1868. break;
  1869. }
  1870. }
  1871. catch (_a) { }
  1872. }
  1873. // If we find the user in a persistence that does support migration, use
  1874. // that migration path (of only persistences that support migration)
  1875. const migrationHierarchy = availablePersistences.filter(p => p._shouldAllowMigration);
  1876. // If the persistence does _not_ allow migration, just finish off here
  1877. if (!selectedPersistence._shouldAllowMigration ||
  1878. !migrationHierarchy.length) {
  1879. return new PersistenceUserManager(selectedPersistence, auth, userKey);
  1880. }
  1881. selectedPersistence = migrationHierarchy[0];
  1882. if (userToMigrate) {
  1883. // This normally shouldn't throw since chosenPersistence.isAvailable() is true, but if it does
  1884. // we'll just let it bubble to surface the error.
  1885. await selectedPersistence._set(key, userToMigrate.toJSON());
  1886. }
  1887. // Attempt to clear the key in other persistences but ignore errors. This helps prevent issues
  1888. // such as users getting stuck with a previous account after signing out and refreshing the tab.
  1889. await Promise.all(persistenceHierarchy.map(async (persistence) => {
  1890. if (persistence !== selectedPersistence) {
  1891. try {
  1892. await persistence._remove(key);
  1893. }
  1894. catch (_a) { }
  1895. }
  1896. }));
  1897. return new PersistenceUserManager(selectedPersistence, auth, userKey);
  1898. }
  1899. }
  1900. /**
  1901. * @license
  1902. * Copyright 2020 Google LLC
  1903. *
  1904. * Licensed under the Apache License, Version 2.0 (the "License");
  1905. * you may not use this file except in compliance with the License.
  1906. * You may obtain a copy of the License at
  1907. *
  1908. * http://www.apache.org/licenses/LICENSE-2.0
  1909. *
  1910. * Unless required by applicable law or agreed to in writing, software
  1911. * distributed under the License is distributed on an "AS IS" BASIS,
  1912. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1913. * See the License for the specific language governing permissions and
  1914. * limitations under the License.
  1915. */
  1916. /**
  1917. * Determine the browser for the purposes of reporting usage to the API
  1918. */
  1919. function _getBrowserName(userAgent) {
  1920. const ua = userAgent.toLowerCase();
  1921. if (ua.includes('opera/') || ua.includes('opr/') || ua.includes('opios/')) {
  1922. return "Opera" /* BrowserName.OPERA */;
  1923. }
  1924. else if (_isIEMobile(ua)) {
  1925. // Windows phone IEMobile browser.
  1926. return "IEMobile" /* BrowserName.IEMOBILE */;
  1927. }
  1928. else if (ua.includes('msie') || ua.includes('trident/')) {
  1929. return "IE" /* BrowserName.IE */;
  1930. }
  1931. else if (ua.includes('edge/')) {
  1932. return "Edge" /* BrowserName.EDGE */;
  1933. }
  1934. else if (_isFirefox(ua)) {
  1935. return "Firefox" /* BrowserName.FIREFOX */;
  1936. }
  1937. else if (ua.includes('silk/')) {
  1938. return "Silk" /* BrowserName.SILK */;
  1939. }
  1940. else if (_isBlackBerry(ua)) {
  1941. // Blackberry browser.
  1942. return "Blackberry" /* BrowserName.BLACKBERRY */;
  1943. }
  1944. else if (_isWebOS(ua)) {
  1945. // WebOS default browser.
  1946. return "Webos" /* BrowserName.WEBOS */;
  1947. }
  1948. else if (_isSafari(ua)) {
  1949. return "Safari" /* BrowserName.SAFARI */;
  1950. }
  1951. else if ((ua.includes('chrome/') || _isChromeIOS(ua)) &&
  1952. !ua.includes('edge/')) {
  1953. return "Chrome" /* BrowserName.CHROME */;
  1954. }
  1955. else if (_isAndroid(ua)) {
  1956. // Android stock browser.
  1957. return "Android" /* BrowserName.ANDROID */;
  1958. }
  1959. else {
  1960. // Most modern browsers have name/version at end of user agent string.
  1961. const re = /([a-zA-Z\d\.]+)\/[a-zA-Z\d\.]*$/;
  1962. const matches = userAgent.match(re);
  1963. if ((matches === null || matches === void 0 ? void 0 : matches.length) === 2) {
  1964. return matches[1];
  1965. }
  1966. }
  1967. return "Other" /* BrowserName.OTHER */;
  1968. }
  1969. function _isFirefox(ua = util.getUA()) {
  1970. return /firefox\//i.test(ua);
  1971. }
  1972. function _isSafari(userAgent = util.getUA()) {
  1973. const ua = userAgent.toLowerCase();
  1974. return (ua.includes('safari/') &&
  1975. !ua.includes('chrome/') &&
  1976. !ua.includes('crios/') &&
  1977. !ua.includes('android'));
  1978. }
  1979. function _isChromeIOS(ua = util.getUA()) {
  1980. return /crios\//i.test(ua);
  1981. }
  1982. function _isIEMobile(ua = util.getUA()) {
  1983. return /iemobile/i.test(ua);
  1984. }
  1985. function _isAndroid(ua = util.getUA()) {
  1986. return /android/i.test(ua);
  1987. }
  1988. function _isBlackBerry(ua = util.getUA()) {
  1989. return /blackberry/i.test(ua);
  1990. }
  1991. function _isWebOS(ua = util.getUA()) {
  1992. return /webos/i.test(ua);
  1993. }
  1994. function _isIOS(ua = util.getUA()) {
  1995. return (/iphone|ipad|ipod/i.test(ua) ||
  1996. (/macintosh/i.test(ua) && /mobile/i.test(ua)));
  1997. }
  1998. function _isIOS7Or8(ua = util.getUA()) {
  1999. return (/(iPad|iPhone|iPod).*OS 7_\d/i.test(ua) ||
  2000. /(iPad|iPhone|iPod).*OS 8_\d/i.test(ua));
  2001. }
  2002. function _isIOSStandalone(ua = util.getUA()) {
  2003. var _a;
  2004. return _isIOS(ua) && !!((_a = window.navigator) === null || _a === void 0 ? void 0 : _a.standalone);
  2005. }
  2006. function _isIE10() {
  2007. return util.isIE() && document.documentMode === 10;
  2008. }
  2009. function _isMobileBrowser(ua = util.getUA()) {
  2010. // TODO: implement getBrowserName equivalent for OS.
  2011. return (_isIOS(ua) ||
  2012. _isAndroid(ua) ||
  2013. _isWebOS(ua) ||
  2014. _isBlackBerry(ua) ||
  2015. /windows phone/i.test(ua) ||
  2016. _isIEMobile(ua));
  2017. }
  2018. function _isIframe() {
  2019. try {
  2020. // Check that the current window is not the top window.
  2021. // If so, return true.
  2022. return !!(window && window !== window.top);
  2023. }
  2024. catch (e) {
  2025. return false;
  2026. }
  2027. }
  2028. /**
  2029. * @license
  2030. * Copyright 2020 Google LLC
  2031. *
  2032. * Licensed under the Apache License, Version 2.0 (the "License");
  2033. * you may not use this file except in compliance with the License.
  2034. * You may obtain a copy of the License at
  2035. *
  2036. * http://www.apache.org/licenses/LICENSE-2.0
  2037. *
  2038. * Unless required by applicable law or agreed to in writing, software
  2039. * distributed under the License is distributed on an "AS IS" BASIS,
  2040. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2041. * See the License for the specific language governing permissions and
  2042. * limitations under the License.
  2043. */
  2044. /*
  2045. * Determine the SDK version string
  2046. */
  2047. function _getClientVersion(clientPlatform, frameworks = []) {
  2048. let reportedPlatform;
  2049. switch (clientPlatform) {
  2050. case "Browser" /* ClientPlatform.BROWSER */:
  2051. // In a browser environment, report the browser name.
  2052. reportedPlatform = _getBrowserName(util.getUA());
  2053. break;
  2054. case "Worker" /* ClientPlatform.WORKER */:
  2055. // Technically a worker runs from a browser but we need to differentiate a
  2056. // worker from a browser.
  2057. // For example: Chrome-Worker/JsCore/4.9.1/FirebaseCore-web.
  2058. reportedPlatform = `${_getBrowserName(util.getUA())}-${clientPlatform}`;
  2059. break;
  2060. default:
  2061. reportedPlatform = clientPlatform;
  2062. }
  2063. const reportedFrameworks = frameworks.length
  2064. ? frameworks.join(',')
  2065. : 'FirebaseCore-web'; /* default value if no other framework is used */
  2066. return `${reportedPlatform}/${"JsCore" /* ClientImplementation.CORE */}/${app.SDK_VERSION}/${reportedFrameworks}`;
  2067. }
  2068. /**
  2069. * @license
  2070. * Copyright 2020 Google LLC
  2071. *
  2072. * Licensed under the Apache License, Version 2.0 (the "License");
  2073. * you may not use this file except in compliance with the License.
  2074. * You may obtain a copy of the License at
  2075. *
  2076. * http://www.apache.org/licenses/LICENSE-2.0
  2077. *
  2078. * Unless required by applicable law or agreed to in writing, software
  2079. * distributed under the License is distributed on an "AS IS" BASIS,
  2080. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2081. * See the License for the specific language governing permissions and
  2082. * limitations under the License.
  2083. */
  2084. async function getRecaptchaParams(auth) {
  2085. return ((await _performApiRequest(auth, "GET" /* HttpMethod.GET */, "/v1/recaptchaParams" /* Endpoint.GET_RECAPTCHA_PARAM */)).recaptchaSiteKey || '');
  2086. }
  2087. async function getRecaptchaConfig(auth, request) {
  2088. return _performApiRequest(auth, "GET" /* HttpMethod.GET */, "/v2/recaptchaConfig" /* Endpoint.GET_RECAPTCHA_CONFIG */, _addTidIfNecessary(auth, request));
  2089. }
  2090. /**
  2091. * @license
  2092. * Copyright 2020 Google LLC
  2093. *
  2094. * Licensed under the Apache License, Version 2.0 (the "License");
  2095. * you may not use this file except in compliance with the License.
  2096. * You may obtain a copy of the License at
  2097. *
  2098. * http://www.apache.org/licenses/LICENSE-2.0
  2099. *
  2100. * Unless required by applicable law or agreed to in writing, software
  2101. * distributed under the License is distributed on an "AS IS" BASIS,
  2102. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2103. * See the License for the specific language governing permissions and
  2104. * limitations under the License.
  2105. */
  2106. function isV2(grecaptcha) {
  2107. return (grecaptcha !== undefined &&
  2108. grecaptcha.getResponse !== undefined);
  2109. }
  2110. function isEnterprise(grecaptcha) {
  2111. return (grecaptcha !== undefined &&
  2112. grecaptcha.enterprise !== undefined);
  2113. }
  2114. class RecaptchaConfig {
  2115. constructor(response) {
  2116. /**
  2117. * The reCAPTCHA site key.
  2118. */
  2119. this.siteKey = '';
  2120. /**
  2121. * The reCAPTCHA enablement status of the {@link EmailAuthProvider} for the current tenant.
  2122. */
  2123. this.emailPasswordEnabled = false;
  2124. if (response.recaptchaKey === undefined) {
  2125. throw new Error('recaptchaKey undefined');
  2126. }
  2127. // Example response.recaptchaKey: "projects/proj123/keys/sitekey123"
  2128. this.siteKey = response.recaptchaKey.split('/')[3];
  2129. this.emailPasswordEnabled = response.recaptchaEnforcementState.some(enforcementState => enforcementState.provider === 'EMAIL_PASSWORD_PROVIDER' &&
  2130. enforcementState.enforcementState !== 'OFF');
  2131. }
  2132. }
  2133. /**
  2134. * @license
  2135. * Copyright 2020 Google LLC
  2136. *
  2137. * Licensed under the Apache License, Version 2.0 (the "License");
  2138. * you may not use this file except in compliance with the License.
  2139. * You may obtain a copy of the License at
  2140. *
  2141. * http://www.apache.org/licenses/LICENSE-2.0
  2142. *
  2143. * Unless required by applicable law or agreed to in writing, software
  2144. * distributed under the License is distributed on an "AS IS" BASIS,
  2145. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2146. * See the License for the specific language governing permissions and
  2147. * limitations under the License.
  2148. */
  2149. function getScriptParentElement() {
  2150. var _a, _b;
  2151. return (_b = (_a = document.getElementsByTagName('head')) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : document;
  2152. }
  2153. function _loadJS(url) {
  2154. // TODO: consider adding timeout support & cancellation
  2155. return new Promise((resolve, reject) => {
  2156. const el = document.createElement('script');
  2157. el.setAttribute('src', url);
  2158. el.onload = resolve;
  2159. el.onerror = e => {
  2160. const error = _createError("internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  2161. error.customData = e;
  2162. reject(error);
  2163. };
  2164. el.type = 'text/javascript';
  2165. el.charset = 'UTF-8';
  2166. getScriptParentElement().appendChild(el);
  2167. });
  2168. }
  2169. function _generateCallbackName(prefix) {
  2170. return `__${prefix}${Math.floor(Math.random() * 1000000)}`;
  2171. }
  2172. /* eslint-disable @typescript-eslint/no-require-imports */
  2173. const RECAPTCHA_ENTERPRISE_URL = 'https://www.google.com/recaptcha/enterprise.js?render=';
  2174. const RECAPTCHA_ENTERPRISE_VERIFIER_TYPE = 'recaptcha-enterprise';
  2175. const FAKE_TOKEN = 'NO_RECAPTCHA';
  2176. class RecaptchaEnterpriseVerifier {
  2177. /**
  2178. *
  2179. * @param authExtern - The corresponding Firebase {@link Auth} instance.
  2180. *
  2181. */
  2182. constructor(authExtern) {
  2183. /**
  2184. * Identifies the type of application verifier (e.g. "recaptcha-enterprise").
  2185. */
  2186. this.type = RECAPTCHA_ENTERPRISE_VERIFIER_TYPE;
  2187. this.auth = _castAuth(authExtern);
  2188. }
  2189. /**
  2190. * Executes the verification process.
  2191. *
  2192. * @returns A Promise for a token that can be used to assert the validity of a request.
  2193. */
  2194. async verify(action = 'verify', forceRefresh = false) {
  2195. async function retrieveSiteKey(auth) {
  2196. if (!forceRefresh) {
  2197. if (auth.tenantId == null && auth._agentRecaptchaConfig != null) {
  2198. return auth._agentRecaptchaConfig.siteKey;
  2199. }
  2200. if (auth.tenantId != null &&
  2201. auth._tenantRecaptchaConfigs[auth.tenantId] !== undefined) {
  2202. return auth._tenantRecaptchaConfigs[auth.tenantId].siteKey;
  2203. }
  2204. }
  2205. return new Promise(async (resolve, reject) => {
  2206. getRecaptchaConfig(auth, {
  2207. clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */,
  2208. version: "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
  2209. })
  2210. .then(response => {
  2211. if (response.recaptchaKey === undefined) {
  2212. reject(new Error('recaptcha Enterprise site key undefined'));
  2213. }
  2214. else {
  2215. const config = new RecaptchaConfig(response);
  2216. if (auth.tenantId == null) {
  2217. auth._agentRecaptchaConfig = config;
  2218. }
  2219. else {
  2220. auth._tenantRecaptchaConfigs[auth.tenantId] = config;
  2221. }
  2222. return resolve(config.siteKey);
  2223. }
  2224. })
  2225. .catch(error => {
  2226. reject(error);
  2227. });
  2228. });
  2229. }
  2230. function retrieveRecaptchaToken(siteKey, resolve, reject) {
  2231. const grecaptcha = window.grecaptcha;
  2232. if (isEnterprise(grecaptcha)) {
  2233. grecaptcha.enterprise.ready(() => {
  2234. grecaptcha.enterprise
  2235. .execute(siteKey, { action })
  2236. .then(token => {
  2237. resolve(token);
  2238. })
  2239. .catch(() => {
  2240. resolve(FAKE_TOKEN);
  2241. });
  2242. });
  2243. }
  2244. else {
  2245. reject(Error('No reCAPTCHA enterprise script loaded.'));
  2246. }
  2247. }
  2248. return new Promise((resolve, reject) => {
  2249. retrieveSiteKey(this.auth)
  2250. .then(siteKey => {
  2251. if (!forceRefresh && isEnterprise(window.grecaptcha)) {
  2252. retrieveRecaptchaToken(siteKey, resolve, reject);
  2253. }
  2254. else {
  2255. if (typeof window === 'undefined') {
  2256. reject(new Error('RecaptchaVerifier is only supported in browser'));
  2257. return;
  2258. }
  2259. _loadJS(RECAPTCHA_ENTERPRISE_URL + siteKey)
  2260. .then(() => {
  2261. retrieveRecaptchaToken(siteKey, resolve, reject);
  2262. })
  2263. .catch(error => {
  2264. reject(error);
  2265. });
  2266. }
  2267. })
  2268. .catch(error => {
  2269. reject(error);
  2270. });
  2271. });
  2272. }
  2273. }
  2274. async function injectRecaptchaFields(auth, request, action, captchaResp = false) {
  2275. const verifier = new RecaptchaEnterpriseVerifier(auth);
  2276. let captchaResponse;
  2277. try {
  2278. captchaResponse = await verifier.verify(action);
  2279. }
  2280. catch (error) {
  2281. captchaResponse = await verifier.verify(action, true);
  2282. }
  2283. const newRequest = Object.assign({}, request);
  2284. if (!captchaResp) {
  2285. Object.assign(newRequest, { captchaResponse });
  2286. }
  2287. else {
  2288. Object.assign(newRequest, { 'captchaResp': captchaResponse });
  2289. }
  2290. Object.assign(newRequest, { 'clientType': "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */ });
  2291. Object.assign(newRequest, {
  2292. 'recaptchaVersion': "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
  2293. });
  2294. return newRequest;
  2295. }
  2296. /**
  2297. * @license
  2298. * Copyright 2022 Google LLC
  2299. *
  2300. * Licensed under the Apache License, Version 2.0 (the "License");
  2301. * you may not use this file except in compliance with the License.
  2302. * You may obtain a copy of the License at
  2303. *
  2304. * http://www.apache.org/licenses/LICENSE-2.0
  2305. *
  2306. * Unless required by applicable law or agreed to in writing, software
  2307. * distributed under the License is distributed on an "AS IS" BASIS,
  2308. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2309. * See the License for the specific language governing permissions and
  2310. * limitations under the License.
  2311. */
  2312. class AuthMiddlewareQueue {
  2313. constructor(auth) {
  2314. this.auth = auth;
  2315. this.queue = [];
  2316. }
  2317. pushCallback(callback, onAbort) {
  2318. // The callback could be sync or async. Wrap it into a
  2319. // function that is always async.
  2320. const wrappedCallback = (user) => new Promise((resolve, reject) => {
  2321. try {
  2322. const result = callback(user);
  2323. // Either resolve with existing promise or wrap a non-promise
  2324. // return value into a promise.
  2325. resolve(result);
  2326. }
  2327. catch (e) {
  2328. // Sync callback throws.
  2329. reject(e);
  2330. }
  2331. });
  2332. // Attach the onAbort if present
  2333. wrappedCallback.onAbort = onAbort;
  2334. this.queue.push(wrappedCallback);
  2335. const index = this.queue.length - 1;
  2336. return () => {
  2337. // Unsubscribe. Replace with no-op. Do not remove from array, or it will disturb
  2338. // indexing of other elements.
  2339. this.queue[index] = () => Promise.resolve();
  2340. };
  2341. }
  2342. async runMiddleware(nextUser) {
  2343. if (this.auth.currentUser === nextUser) {
  2344. return;
  2345. }
  2346. // While running the middleware, build a temporary stack of onAbort
  2347. // callbacks to call if one middleware callback rejects.
  2348. const onAbortStack = [];
  2349. try {
  2350. for (const beforeStateCallback of this.queue) {
  2351. await beforeStateCallback(nextUser);
  2352. // Only push the onAbort if the callback succeeds
  2353. if (beforeStateCallback.onAbort) {
  2354. onAbortStack.push(beforeStateCallback.onAbort);
  2355. }
  2356. }
  2357. }
  2358. catch (e) {
  2359. // Run all onAbort, with separate try/catch to ignore any errors and
  2360. // continue
  2361. onAbortStack.reverse();
  2362. for (const onAbort of onAbortStack) {
  2363. try {
  2364. onAbort();
  2365. }
  2366. catch (_) {
  2367. /* swallow error */
  2368. }
  2369. }
  2370. throw this.auth._errorFactory.create("login-blocked" /* AuthErrorCode.LOGIN_BLOCKED */, {
  2371. originalMessage: e === null || e === void 0 ? void 0 : e.message
  2372. });
  2373. }
  2374. }
  2375. }
  2376. /**
  2377. * @license
  2378. * Copyright 2020 Google LLC
  2379. *
  2380. * Licensed under the Apache License, Version 2.0 (the "License");
  2381. * you may not use this file except in compliance with the License.
  2382. * You may obtain a copy of the License at
  2383. *
  2384. * http://www.apache.org/licenses/LICENSE-2.0
  2385. *
  2386. * Unless required by applicable law or agreed to in writing, software
  2387. * distributed under the License is distributed on an "AS IS" BASIS,
  2388. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2389. * See the License for the specific language governing permissions and
  2390. * limitations under the License.
  2391. */
  2392. class AuthImpl {
  2393. constructor(app, heartbeatServiceProvider, appCheckServiceProvider, config) {
  2394. this.app = app;
  2395. this.heartbeatServiceProvider = heartbeatServiceProvider;
  2396. this.appCheckServiceProvider = appCheckServiceProvider;
  2397. this.config = config;
  2398. this.currentUser = null;
  2399. this.emulatorConfig = null;
  2400. this.operations = Promise.resolve();
  2401. this.authStateSubscription = new Subscription(this);
  2402. this.idTokenSubscription = new Subscription(this);
  2403. this.beforeStateQueue = new AuthMiddlewareQueue(this);
  2404. this.redirectUser = null;
  2405. this.isProactiveRefreshEnabled = false;
  2406. // Any network calls will set this to true and prevent subsequent emulator
  2407. // initialization
  2408. this._canInitEmulator = true;
  2409. this._isInitialized = false;
  2410. this._deleted = false;
  2411. this._initializationPromise = null;
  2412. this._popupRedirectResolver = null;
  2413. this._errorFactory = _DEFAULT_AUTH_ERROR_FACTORY;
  2414. this._agentRecaptchaConfig = null;
  2415. this._tenantRecaptchaConfigs = {};
  2416. // Tracks the last notified UID for state change listeners to prevent
  2417. // repeated calls to the callbacks. Undefined means it's never been
  2418. // called, whereas null means it's been called with a signed out user
  2419. this.lastNotifiedUid = undefined;
  2420. this.languageCode = null;
  2421. this.tenantId = null;
  2422. this.settings = { appVerificationDisabledForTesting: false };
  2423. this.frameworks = [];
  2424. this.name = app.name;
  2425. this.clientVersion = config.sdkClientVersion;
  2426. }
  2427. _initializeWithPersistence(persistenceHierarchy, popupRedirectResolver) {
  2428. if (popupRedirectResolver) {
  2429. this._popupRedirectResolver = _getInstance(popupRedirectResolver);
  2430. }
  2431. // Have to check for app deletion throughout initialization (after each
  2432. // promise resolution)
  2433. this._initializationPromise = this.queue(async () => {
  2434. var _a, _b;
  2435. if (this._deleted) {
  2436. return;
  2437. }
  2438. this.persistenceManager = await PersistenceUserManager.create(this, persistenceHierarchy);
  2439. if (this._deleted) {
  2440. return;
  2441. }
  2442. // Initialize the resolver early if necessary (only applicable to web:
  2443. // this will cause the iframe to load immediately in certain cases)
  2444. if ((_a = this._popupRedirectResolver) === null || _a === void 0 ? void 0 : _a._shouldInitProactively) {
  2445. // If this fails, don't halt auth loading
  2446. try {
  2447. await this._popupRedirectResolver._initialize(this);
  2448. }
  2449. catch (e) {
  2450. /* Ignore the error */
  2451. }
  2452. }
  2453. await this.initializeCurrentUser(popupRedirectResolver);
  2454. this.lastNotifiedUid = ((_b = this.currentUser) === null || _b === void 0 ? void 0 : _b.uid) || null;
  2455. if (this._deleted) {
  2456. return;
  2457. }
  2458. this._isInitialized = true;
  2459. });
  2460. return this._initializationPromise;
  2461. }
  2462. /**
  2463. * If the persistence is changed in another window, the user manager will let us know
  2464. */
  2465. async _onStorageEvent() {
  2466. if (this._deleted) {
  2467. return;
  2468. }
  2469. const user = await this.assertedPersistence.getCurrentUser();
  2470. if (!this.currentUser && !user) {
  2471. // No change, do nothing (was signed out and remained signed out).
  2472. return;
  2473. }
  2474. // If the same user is to be synchronized.
  2475. if (this.currentUser && user && this.currentUser.uid === user.uid) {
  2476. // Data update, simply copy data changes.
  2477. this._currentUser._assign(user);
  2478. // If tokens changed from previous user tokens, this will trigger
  2479. // notifyAuthListeners_.
  2480. await this.currentUser.getIdToken();
  2481. return;
  2482. }
  2483. // Update current Auth state. Either a new login or logout.
  2484. // Skip blocking callbacks, they should not apply to a change in another tab.
  2485. await this._updateCurrentUser(user, /* skipBeforeStateCallbacks */ true);
  2486. }
  2487. async initializeCurrentUser(popupRedirectResolver) {
  2488. var _a;
  2489. // First check to see if we have a pending redirect event.
  2490. const previouslyStoredUser = (await this.assertedPersistence.getCurrentUser());
  2491. let futureCurrentUser = previouslyStoredUser;
  2492. let needsTocheckMiddleware = false;
  2493. if (popupRedirectResolver && this.config.authDomain) {
  2494. await this.getOrInitRedirectPersistenceManager();
  2495. const redirectUserEventId = (_a = this.redirectUser) === null || _a === void 0 ? void 0 : _a._redirectEventId;
  2496. const storedUserEventId = futureCurrentUser === null || futureCurrentUser === void 0 ? void 0 : futureCurrentUser._redirectEventId;
  2497. const result = await this.tryRedirectSignIn(popupRedirectResolver);
  2498. // If the stored user (i.e. the old "currentUser") has a redirectId that
  2499. // matches the redirect user, then we want to initially sign in with the
  2500. // new user object from result.
  2501. // TODO(samgho): More thoroughly test all of this
  2502. if ((!redirectUserEventId || redirectUserEventId === storedUserEventId) &&
  2503. (result === null || result === void 0 ? void 0 : result.user)) {
  2504. futureCurrentUser = result.user;
  2505. needsTocheckMiddleware = true;
  2506. }
  2507. }
  2508. // If no user in persistence, there is no current user. Set to null.
  2509. if (!futureCurrentUser) {
  2510. return this.directlySetCurrentUser(null);
  2511. }
  2512. if (!futureCurrentUser._redirectEventId) {
  2513. // This isn't a redirect link operation, we can reload and bail.
  2514. // First though, ensure that we check the middleware is happy.
  2515. if (needsTocheckMiddleware) {
  2516. try {
  2517. await this.beforeStateQueue.runMiddleware(futureCurrentUser);
  2518. }
  2519. catch (e) {
  2520. futureCurrentUser = previouslyStoredUser;
  2521. // We know this is available since the bit is only set when the
  2522. // resolver is available
  2523. this._popupRedirectResolver._overrideRedirectResult(this, () => Promise.reject(e));
  2524. }
  2525. }
  2526. if (futureCurrentUser) {
  2527. return this.reloadAndSetCurrentUserOrClear(futureCurrentUser);
  2528. }
  2529. else {
  2530. return this.directlySetCurrentUser(null);
  2531. }
  2532. }
  2533. _assert(this._popupRedirectResolver, this, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  2534. await this.getOrInitRedirectPersistenceManager();
  2535. // If the redirect user's event ID matches the current user's event ID,
  2536. // DO NOT reload the current user, otherwise they'll be cleared from storage.
  2537. // This is important for the reauthenticateWithRedirect() flow.
  2538. if (this.redirectUser &&
  2539. this.redirectUser._redirectEventId === futureCurrentUser._redirectEventId) {
  2540. return this.directlySetCurrentUser(futureCurrentUser);
  2541. }
  2542. return this.reloadAndSetCurrentUserOrClear(futureCurrentUser);
  2543. }
  2544. async tryRedirectSignIn(redirectResolver) {
  2545. // The redirect user needs to be checked (and signed in if available)
  2546. // during auth initialization. All of the normal sign in and link/reauth
  2547. // flows call back into auth and push things onto the promise queue. We
  2548. // need to await the result of the redirect sign in *inside the promise
  2549. // queue*. This presents a problem: we run into deadlock. See:
  2550. // ┌> [Initialization] ─────┐
  2551. // ┌> [<other queue tasks>] │
  2552. // └─ [getRedirectResult] <─┘
  2553. // where [] are tasks on the queue and arrows denote awaits
  2554. // Initialization will never complete because it's waiting on something
  2555. // that's waiting for initialization to complete!
  2556. //
  2557. // Instead, this method calls getRedirectResult() (stored in
  2558. // _completeRedirectFn) with an optional parameter that instructs all of
  2559. // the underlying auth operations to skip anything that mutates auth state.
  2560. let result = null;
  2561. try {
  2562. // We know this._popupRedirectResolver is set since redirectResolver
  2563. // is passed in. The _completeRedirectFn expects the unwrapped extern.
  2564. result = await this._popupRedirectResolver._completeRedirectFn(this, redirectResolver, true);
  2565. }
  2566. catch (e) {
  2567. // Swallow any errors here; the code can retrieve them in
  2568. // getRedirectResult().
  2569. await this._setRedirectUser(null);
  2570. }
  2571. return result;
  2572. }
  2573. async reloadAndSetCurrentUserOrClear(user) {
  2574. try {
  2575. await _reloadWithoutSaving(user);
  2576. }
  2577. catch (e) {
  2578. if ((e === null || e === void 0 ? void 0 : e.code) !==
  2579. `auth/${"network-request-failed" /* AuthErrorCode.NETWORK_REQUEST_FAILED */}`) {
  2580. // Something's wrong with the user's token. Log them out and remove
  2581. // them from storage
  2582. return this.directlySetCurrentUser(null);
  2583. }
  2584. }
  2585. return this.directlySetCurrentUser(user);
  2586. }
  2587. useDeviceLanguage() {
  2588. this.languageCode = _getUserLanguage();
  2589. }
  2590. async _delete() {
  2591. this._deleted = true;
  2592. }
  2593. async updateCurrentUser(userExtern) {
  2594. // The public updateCurrentUser method needs to make a copy of the user,
  2595. // and also check that the project matches
  2596. const user = userExtern
  2597. ? util.getModularInstance(userExtern)
  2598. : null;
  2599. if (user) {
  2600. _assert(user.auth.config.apiKey === this.config.apiKey, this, "invalid-user-token" /* AuthErrorCode.INVALID_AUTH */);
  2601. }
  2602. return this._updateCurrentUser(user && user._clone(this));
  2603. }
  2604. async _updateCurrentUser(user, skipBeforeStateCallbacks = false) {
  2605. if (this._deleted) {
  2606. return;
  2607. }
  2608. if (user) {
  2609. _assert(this.tenantId === user.tenantId, this, "tenant-id-mismatch" /* AuthErrorCode.TENANT_ID_MISMATCH */);
  2610. }
  2611. if (!skipBeforeStateCallbacks) {
  2612. await this.beforeStateQueue.runMiddleware(user);
  2613. }
  2614. return this.queue(async () => {
  2615. await this.directlySetCurrentUser(user);
  2616. this.notifyAuthListeners();
  2617. });
  2618. }
  2619. async signOut() {
  2620. // Run first, to block _setRedirectUser() if any callbacks fail.
  2621. await this.beforeStateQueue.runMiddleware(null);
  2622. // Clear the redirect user when signOut is called
  2623. if (this.redirectPersistenceManager || this._popupRedirectResolver) {
  2624. await this._setRedirectUser(null);
  2625. }
  2626. // Prevent callbacks from being called again in _updateCurrentUser, as
  2627. // they were already called in the first line.
  2628. return this._updateCurrentUser(null, /* skipBeforeStateCallbacks */ true);
  2629. }
  2630. setPersistence(persistence) {
  2631. return this.queue(async () => {
  2632. await this.assertedPersistence.setPersistence(_getInstance(persistence));
  2633. });
  2634. }
  2635. async initializeRecaptchaConfig() {
  2636. const response = await getRecaptchaConfig(this, {
  2637. clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */,
  2638. version: "RECAPTCHA_ENTERPRISE" /* RecaptchaVersion.ENTERPRISE */
  2639. });
  2640. const config = new RecaptchaConfig(response);
  2641. if (this.tenantId == null) {
  2642. this._agentRecaptchaConfig = config;
  2643. }
  2644. else {
  2645. this._tenantRecaptchaConfigs[this.tenantId] = config;
  2646. }
  2647. if (config.emailPasswordEnabled) {
  2648. const verifier = new RecaptchaEnterpriseVerifier(this);
  2649. void verifier.verify();
  2650. }
  2651. }
  2652. _getRecaptchaConfig() {
  2653. if (this.tenantId == null) {
  2654. return this._agentRecaptchaConfig;
  2655. }
  2656. else {
  2657. return this._tenantRecaptchaConfigs[this.tenantId];
  2658. }
  2659. }
  2660. _getPersistence() {
  2661. return this.assertedPersistence.persistence.type;
  2662. }
  2663. _updateErrorMap(errorMap) {
  2664. this._errorFactory = new util.ErrorFactory('auth', 'Firebase', errorMap());
  2665. }
  2666. onAuthStateChanged(nextOrObserver, error, completed) {
  2667. return this.registerStateListener(this.authStateSubscription, nextOrObserver, error, completed);
  2668. }
  2669. beforeAuthStateChanged(callback, onAbort) {
  2670. return this.beforeStateQueue.pushCallback(callback, onAbort);
  2671. }
  2672. onIdTokenChanged(nextOrObserver, error, completed) {
  2673. return this.registerStateListener(this.idTokenSubscription, nextOrObserver, error, completed);
  2674. }
  2675. toJSON() {
  2676. var _a;
  2677. return {
  2678. apiKey: this.config.apiKey,
  2679. authDomain: this.config.authDomain,
  2680. appName: this.name,
  2681. currentUser: (_a = this._currentUser) === null || _a === void 0 ? void 0 : _a.toJSON()
  2682. };
  2683. }
  2684. async _setRedirectUser(user, popupRedirectResolver) {
  2685. const redirectManager = await this.getOrInitRedirectPersistenceManager(popupRedirectResolver);
  2686. return user === null
  2687. ? redirectManager.removeCurrentUser()
  2688. : redirectManager.setCurrentUser(user);
  2689. }
  2690. async getOrInitRedirectPersistenceManager(popupRedirectResolver) {
  2691. if (!this.redirectPersistenceManager) {
  2692. const resolver = (popupRedirectResolver && _getInstance(popupRedirectResolver)) ||
  2693. this._popupRedirectResolver;
  2694. _assert(resolver, this, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  2695. this.redirectPersistenceManager = await PersistenceUserManager.create(this, [_getInstance(resolver._redirectPersistence)], "redirectUser" /* KeyName.REDIRECT_USER */);
  2696. this.redirectUser =
  2697. await this.redirectPersistenceManager.getCurrentUser();
  2698. }
  2699. return this.redirectPersistenceManager;
  2700. }
  2701. async _redirectUserForId(id) {
  2702. var _a, _b;
  2703. // Make sure we've cleared any pending persistence actions if we're not in
  2704. // the initializer
  2705. if (this._isInitialized) {
  2706. await this.queue(async () => { });
  2707. }
  2708. if (((_a = this._currentUser) === null || _a === void 0 ? void 0 : _a._redirectEventId) === id) {
  2709. return this._currentUser;
  2710. }
  2711. if (((_b = this.redirectUser) === null || _b === void 0 ? void 0 : _b._redirectEventId) === id) {
  2712. return this.redirectUser;
  2713. }
  2714. return null;
  2715. }
  2716. async _persistUserIfCurrent(user) {
  2717. if (user === this.currentUser) {
  2718. return this.queue(async () => this.directlySetCurrentUser(user));
  2719. }
  2720. }
  2721. /** Notifies listeners only if the user is current */
  2722. _notifyListenersIfCurrent(user) {
  2723. if (user === this.currentUser) {
  2724. this.notifyAuthListeners();
  2725. }
  2726. }
  2727. _key() {
  2728. return `${this.config.authDomain}:${this.config.apiKey}:${this.name}`;
  2729. }
  2730. _startProactiveRefresh() {
  2731. this.isProactiveRefreshEnabled = true;
  2732. if (this.currentUser) {
  2733. this._currentUser._startProactiveRefresh();
  2734. }
  2735. }
  2736. _stopProactiveRefresh() {
  2737. this.isProactiveRefreshEnabled = false;
  2738. if (this.currentUser) {
  2739. this._currentUser._stopProactiveRefresh();
  2740. }
  2741. }
  2742. /** Returns the current user cast as the internal type */
  2743. get _currentUser() {
  2744. return this.currentUser;
  2745. }
  2746. notifyAuthListeners() {
  2747. var _a, _b;
  2748. if (!this._isInitialized) {
  2749. return;
  2750. }
  2751. this.idTokenSubscription.next(this.currentUser);
  2752. const currentUid = (_b = (_a = this.currentUser) === null || _a === void 0 ? void 0 : _a.uid) !== null && _b !== void 0 ? _b : null;
  2753. if (this.lastNotifiedUid !== currentUid) {
  2754. this.lastNotifiedUid = currentUid;
  2755. this.authStateSubscription.next(this.currentUser);
  2756. }
  2757. }
  2758. registerStateListener(subscription, nextOrObserver, error, completed) {
  2759. if (this._deleted) {
  2760. return () => { };
  2761. }
  2762. const cb = typeof nextOrObserver === 'function'
  2763. ? nextOrObserver
  2764. : nextOrObserver.next.bind(nextOrObserver);
  2765. const promise = this._isInitialized
  2766. ? Promise.resolve()
  2767. : this._initializationPromise;
  2768. _assert(promise, this, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  2769. // The callback needs to be called asynchronously per the spec.
  2770. // eslint-disable-next-line @typescript-eslint/no-floating-promises
  2771. promise.then(() => cb(this.currentUser));
  2772. if (typeof nextOrObserver === 'function') {
  2773. return subscription.addObserver(nextOrObserver, error, completed);
  2774. }
  2775. else {
  2776. return subscription.addObserver(nextOrObserver);
  2777. }
  2778. }
  2779. /**
  2780. * Unprotected (from race conditions) method to set the current user. This
  2781. * should only be called from within a queued callback. This is necessary
  2782. * because the queue shouldn't rely on another queued callback.
  2783. */
  2784. async directlySetCurrentUser(user) {
  2785. if (this.currentUser && this.currentUser !== user) {
  2786. this._currentUser._stopProactiveRefresh();
  2787. }
  2788. if (user && this.isProactiveRefreshEnabled) {
  2789. user._startProactiveRefresh();
  2790. }
  2791. this.currentUser = user;
  2792. if (user) {
  2793. await this.assertedPersistence.setCurrentUser(user);
  2794. }
  2795. else {
  2796. await this.assertedPersistence.removeCurrentUser();
  2797. }
  2798. }
  2799. queue(action) {
  2800. // In case something errors, the callback still should be called in order
  2801. // to keep the promise chain alive
  2802. this.operations = this.operations.then(action, action);
  2803. return this.operations;
  2804. }
  2805. get assertedPersistence() {
  2806. _assert(this.persistenceManager, this, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  2807. return this.persistenceManager;
  2808. }
  2809. _logFramework(framework) {
  2810. if (!framework || this.frameworks.includes(framework)) {
  2811. return;
  2812. }
  2813. this.frameworks.push(framework);
  2814. // Sort alphabetically so that "FirebaseCore-web,FirebaseUI-web" and
  2815. // "FirebaseUI-web,FirebaseCore-web" aren't viewed as different.
  2816. this.frameworks.sort();
  2817. this.clientVersion = _getClientVersion(this.config.clientPlatform, this._getFrameworks());
  2818. }
  2819. _getFrameworks() {
  2820. return this.frameworks;
  2821. }
  2822. async _getAdditionalHeaders() {
  2823. var _a;
  2824. // Additional headers on every request
  2825. const headers = {
  2826. ["X-Client-Version" /* HttpHeader.X_CLIENT_VERSION */]: this.clientVersion
  2827. };
  2828. if (this.app.options.appId) {
  2829. headers["X-Firebase-gmpid" /* HttpHeader.X_FIREBASE_GMPID */] = this.app.options.appId;
  2830. }
  2831. // If the heartbeat service exists, add the heartbeat string
  2832. const heartbeatsHeader = await ((_a = this.heartbeatServiceProvider
  2833. .getImmediate({
  2834. optional: true
  2835. })) === null || _a === void 0 ? void 0 : _a.getHeartbeatsHeader());
  2836. if (heartbeatsHeader) {
  2837. headers["X-Firebase-Client" /* HttpHeader.X_FIREBASE_CLIENT */] = heartbeatsHeader;
  2838. }
  2839. // If the App Check service exists, add the App Check token in the headers
  2840. const appCheckToken = await this._getAppCheckToken();
  2841. if (appCheckToken) {
  2842. headers["X-Firebase-AppCheck" /* HttpHeader.X_FIREBASE_APP_CHECK */] = appCheckToken;
  2843. }
  2844. return headers;
  2845. }
  2846. async _getAppCheckToken() {
  2847. var _a;
  2848. const appCheckTokenResult = await ((_a = this.appCheckServiceProvider
  2849. .getImmediate({ optional: true })) === null || _a === void 0 ? void 0 : _a.getToken());
  2850. if (appCheckTokenResult === null || appCheckTokenResult === void 0 ? void 0 : appCheckTokenResult.error) {
  2851. // Context: appCheck.getToken() will never throw even if an error happened.
  2852. // In the error case, a dummy token will be returned along with an error field describing
  2853. // the error. In general, we shouldn't care about the error condition and just use
  2854. // the token (actual or dummy) to send requests.
  2855. _logWarn(`Error while retrieving App Check token: ${appCheckTokenResult.error}`);
  2856. }
  2857. return appCheckTokenResult === null || appCheckTokenResult === void 0 ? void 0 : appCheckTokenResult.token;
  2858. }
  2859. }
  2860. /**
  2861. * Method to be used to cast down to our private implmentation of Auth.
  2862. * It will also handle unwrapping from the compat type if necessary
  2863. *
  2864. * @param auth Auth object passed in from developer
  2865. */
  2866. function _castAuth(auth) {
  2867. return util.getModularInstance(auth);
  2868. }
  2869. /** Helper class to wrap subscriber logic */
  2870. class Subscription {
  2871. constructor(auth) {
  2872. this.auth = auth;
  2873. this.observer = null;
  2874. this.addObserver = util.createSubscribe(observer => (this.observer = observer));
  2875. }
  2876. get next() {
  2877. _assert(this.observer, this.auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  2878. return this.observer.next.bind(this.observer);
  2879. }
  2880. }
  2881. /**
  2882. * @license
  2883. * Copyright 2020 Google LLC
  2884. *
  2885. * Licensed under the Apache License, Version 2.0 (the "License");
  2886. * you may not use this file except in compliance with the License.
  2887. * You may obtain a copy of the License at
  2888. *
  2889. * http://www.apache.org/licenses/LICENSE-2.0
  2890. *
  2891. * Unless required by applicable law or agreed to in writing, software
  2892. * distributed under the License is distributed on an "AS IS" BASIS,
  2893. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2894. * See the License for the specific language governing permissions and
  2895. * limitations under the License.
  2896. */
  2897. /**
  2898. * Initializes an {@link Auth} instance with fine-grained control over
  2899. * {@link Dependencies}.
  2900. *
  2901. * @remarks
  2902. *
  2903. * This function allows more control over the {@link Auth} instance than
  2904. * {@link getAuth}. `getAuth` uses platform-specific defaults to supply
  2905. * the {@link Dependencies}. In general, `getAuth` is the easiest way to
  2906. * initialize Auth and works for most use cases. Use `initializeAuth` if you
  2907. * need control over which persistence layer is used, or to minimize bundle
  2908. * size if you're not using either `signInWithPopup` or `signInWithRedirect`.
  2909. *
  2910. * For example, if your app only uses anonymous accounts and you only want
  2911. * accounts saved for the current session, initialize `Auth` with:
  2912. *
  2913. * ```js
  2914. * const auth = initializeAuth(app, {
  2915. * persistence: browserSessionPersistence,
  2916. * popupRedirectResolver: undefined,
  2917. * });
  2918. * ```
  2919. *
  2920. * @public
  2921. */
  2922. function initializeAuth(app$1, deps) {
  2923. const provider = app._getProvider(app$1, 'auth');
  2924. if (provider.isInitialized()) {
  2925. const auth = provider.getImmediate();
  2926. const initialOptions = provider.getOptions();
  2927. if (util.deepEqual(initialOptions, deps !== null && deps !== void 0 ? deps : {})) {
  2928. return auth;
  2929. }
  2930. else {
  2931. _fail(auth, "already-initialized" /* AuthErrorCode.ALREADY_INITIALIZED */);
  2932. }
  2933. }
  2934. const auth = provider.initialize({ options: deps });
  2935. return auth;
  2936. }
  2937. function _initializeAuthInstance(auth, deps) {
  2938. const persistence = (deps === null || deps === void 0 ? void 0 : deps.persistence) || [];
  2939. const hierarchy = (Array.isArray(persistence) ? persistence : [persistence]).map(_getInstance);
  2940. if (deps === null || deps === void 0 ? void 0 : deps.errorMap) {
  2941. auth._updateErrorMap(deps.errorMap);
  2942. }
  2943. // This promise is intended to float; auth initialization happens in the
  2944. // background, meanwhile the auth object may be used by the app.
  2945. // eslint-disable-next-line @typescript-eslint/no-floating-promises
  2946. auth._initializeWithPersistence(hierarchy, deps === null || deps === void 0 ? void 0 : deps.popupRedirectResolver);
  2947. }
  2948. /**
  2949. * Changes the {@link Auth} instance to communicate with the Firebase Auth Emulator, instead of production
  2950. * Firebase Auth services.
  2951. *
  2952. * @remarks
  2953. * This must be called synchronously immediately following the first call to
  2954. * {@link initializeAuth}. Do not use with production credentials as emulator
  2955. * traffic is not encrypted.
  2956. *
  2957. *
  2958. * @example
  2959. * ```javascript
  2960. * connectAuthEmulator(auth, 'http://127.0.0.1:9099', { disableWarnings: true });
  2961. * ```
  2962. *
  2963. * @param auth - The {@link Auth} instance.
  2964. * @param url - The URL at which the emulator is running (eg, 'http://localhost:9099').
  2965. * @param options - Optional. `options.disableWarnings` defaults to `false`. Set it to
  2966. * `true` to disable the warning banner attached to the DOM.
  2967. *
  2968. * @public
  2969. */
  2970. function connectAuthEmulator(auth, url, options) {
  2971. const authInternal = _castAuth(auth);
  2972. _assert(authInternal._canInitEmulator, authInternal, "emulator-config-failed" /* AuthErrorCode.EMULATOR_CONFIG_FAILED */);
  2973. _assert(/^https?:\/\//.test(url), authInternal, "invalid-emulator-scheme" /* AuthErrorCode.INVALID_EMULATOR_SCHEME */);
  2974. const disableWarnings = !!(options === null || options === void 0 ? void 0 : options.disableWarnings);
  2975. const protocol = extractProtocol(url);
  2976. const { host, port } = extractHostAndPort(url);
  2977. const portStr = port === null ? '' : `:${port}`;
  2978. // Always replace path with "/" (even if input url had no path at all, or had a different one).
  2979. authInternal.config.emulator = { url: `${protocol}//${host}${portStr}/` };
  2980. authInternal.settings.appVerificationDisabledForTesting = true;
  2981. authInternal.emulatorConfig = Object.freeze({
  2982. host,
  2983. port,
  2984. protocol: protocol.replace(':', ''),
  2985. options: Object.freeze({ disableWarnings })
  2986. });
  2987. if (!disableWarnings) {
  2988. emitEmulatorWarning();
  2989. }
  2990. }
  2991. function extractProtocol(url) {
  2992. const protocolEnd = url.indexOf(':');
  2993. return protocolEnd < 0 ? '' : url.substr(0, protocolEnd + 1);
  2994. }
  2995. function extractHostAndPort(url) {
  2996. const protocol = extractProtocol(url);
  2997. const authority = /(\/\/)?([^?#/]+)/.exec(url.substr(protocol.length)); // Between // and /, ? or #.
  2998. if (!authority) {
  2999. return { host: '', port: null };
  3000. }
  3001. const hostAndPort = authority[2].split('@').pop() || ''; // Strip out "username:password@".
  3002. const bracketedIPv6 = /^(\[[^\]]+\])(:|$)/.exec(hostAndPort);
  3003. if (bracketedIPv6) {
  3004. const host = bracketedIPv6[1];
  3005. return { host, port: parsePort(hostAndPort.substr(host.length + 1)) };
  3006. }
  3007. else {
  3008. const [host, port] = hostAndPort.split(':');
  3009. return { host, port: parsePort(port) };
  3010. }
  3011. }
  3012. function parsePort(portStr) {
  3013. if (!portStr) {
  3014. return null;
  3015. }
  3016. const port = Number(portStr);
  3017. if (isNaN(port)) {
  3018. return null;
  3019. }
  3020. return port;
  3021. }
  3022. function emitEmulatorWarning() {
  3023. function attachBanner() {
  3024. const el = document.createElement('p');
  3025. const sty = el.style;
  3026. el.innerText =
  3027. 'Running in emulator mode. Do not use with production credentials.';
  3028. sty.position = 'fixed';
  3029. sty.width = '100%';
  3030. sty.backgroundColor = '#ffffff';
  3031. sty.border = '.1em solid #000000';
  3032. sty.color = '#b50000';
  3033. sty.bottom = '0px';
  3034. sty.left = '0px';
  3035. sty.margin = '0px';
  3036. sty.zIndex = '10000';
  3037. sty.textAlign = 'center';
  3038. el.classList.add('firebase-emulator-warning');
  3039. document.body.appendChild(el);
  3040. }
  3041. if (typeof console !== 'undefined' && typeof console.info === 'function') {
  3042. console.info('WARNING: You are using the Auth Emulator,' +
  3043. ' which is intended for local testing only. Do not use with' +
  3044. ' production credentials.');
  3045. }
  3046. if (typeof window !== 'undefined' && typeof document !== 'undefined') {
  3047. if (document.readyState === 'loading') {
  3048. window.addEventListener('DOMContentLoaded', attachBanner);
  3049. }
  3050. else {
  3051. attachBanner();
  3052. }
  3053. }
  3054. }
  3055. /**
  3056. * @license
  3057. * Copyright 2020 Google LLC
  3058. *
  3059. * Licensed under the Apache License, Version 2.0 (the "License");
  3060. * you may not use this file except in compliance with the License.
  3061. * You may obtain a copy of the License at
  3062. *
  3063. * http://www.apache.org/licenses/LICENSE-2.0
  3064. *
  3065. * Unless required by applicable law or agreed to in writing, software
  3066. * distributed under the License is distributed on an "AS IS" BASIS,
  3067. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3068. * See the License for the specific language governing permissions and
  3069. * limitations under the License.
  3070. */
  3071. /**
  3072. * Interface that represents the credentials returned by an {@link AuthProvider}.
  3073. *
  3074. * @remarks
  3075. * Implementations specify the details about each auth provider's credential requirements.
  3076. *
  3077. * @public
  3078. */
  3079. class AuthCredential {
  3080. /** @internal */
  3081. constructor(
  3082. /**
  3083. * The authentication provider ID for the credential.
  3084. *
  3085. * @remarks
  3086. * For example, 'facebook.com', or 'google.com'.
  3087. */
  3088. providerId,
  3089. /**
  3090. * The authentication sign in method for the credential.
  3091. *
  3092. * @remarks
  3093. * For example, {@link SignInMethod}.EMAIL_PASSWORD, or
  3094. * {@link SignInMethod}.EMAIL_LINK. This corresponds to the sign-in method
  3095. * identifier as returned in {@link fetchSignInMethodsForEmail}.
  3096. */
  3097. signInMethod) {
  3098. this.providerId = providerId;
  3099. this.signInMethod = signInMethod;
  3100. }
  3101. /**
  3102. * Returns a JSON-serializable representation of this object.
  3103. *
  3104. * @returns a JSON-serializable representation of this object.
  3105. */
  3106. toJSON() {
  3107. return debugFail('not implemented');
  3108. }
  3109. /** @internal */
  3110. _getIdTokenResponse(_auth) {
  3111. return debugFail('not implemented');
  3112. }
  3113. /** @internal */
  3114. _linkToIdToken(_auth, _idToken) {
  3115. return debugFail('not implemented');
  3116. }
  3117. /** @internal */
  3118. _getReauthenticationResolver(_auth) {
  3119. return debugFail('not implemented');
  3120. }
  3121. }
  3122. /**
  3123. * @license
  3124. * Copyright 2020 Google LLC
  3125. *
  3126. * Licensed under the Apache License, Version 2.0 (the "License");
  3127. * you may not use this file except in compliance with the License.
  3128. * You may obtain a copy of the License at
  3129. *
  3130. * http://www.apache.org/licenses/LICENSE-2.0
  3131. *
  3132. * Unless required by applicable law or agreed to in writing, software
  3133. * distributed under the License is distributed on an "AS IS" BASIS,
  3134. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3135. * See the License for the specific language governing permissions and
  3136. * limitations under the License.
  3137. */
  3138. async function resetPassword(auth, request) {
  3139. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:resetPassword" /* Endpoint.RESET_PASSWORD */, _addTidIfNecessary(auth, request));
  3140. }
  3141. async function updateEmailPassword(auth, request) {
  3142. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:update" /* Endpoint.SET_ACCOUNT_INFO */, request);
  3143. }
  3144. async function applyActionCode$1(auth, request) {
  3145. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:update" /* Endpoint.SET_ACCOUNT_INFO */, _addTidIfNecessary(auth, request));
  3146. }
  3147. /**
  3148. * @license
  3149. * Copyright 2020 Google LLC
  3150. *
  3151. * Licensed under the Apache License, Version 2.0 (the "License");
  3152. * you may not use this file except in compliance with the License.
  3153. * You may obtain a copy of the License at
  3154. *
  3155. * http://www.apache.org/licenses/LICENSE-2.0
  3156. *
  3157. * Unless required by applicable law or agreed to in writing, software
  3158. * distributed under the License is distributed on an "AS IS" BASIS,
  3159. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3160. * See the License for the specific language governing permissions and
  3161. * limitations under the License.
  3162. */
  3163. async function signInWithPassword(auth, request) {
  3164. return _performSignInRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:signInWithPassword" /* Endpoint.SIGN_IN_WITH_PASSWORD */, _addTidIfNecessary(auth, request));
  3165. }
  3166. async function sendOobCode(auth, request) {
  3167. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:sendOobCode" /* Endpoint.SEND_OOB_CODE */, _addTidIfNecessary(auth, request));
  3168. }
  3169. async function sendEmailVerification$1(auth, request) {
  3170. return sendOobCode(auth, request);
  3171. }
  3172. async function sendPasswordResetEmail$1(auth, request) {
  3173. return sendOobCode(auth, request);
  3174. }
  3175. async function sendSignInLinkToEmail$1(auth, request) {
  3176. return sendOobCode(auth, request);
  3177. }
  3178. async function verifyAndChangeEmail(auth, request) {
  3179. return sendOobCode(auth, request);
  3180. }
  3181. /**
  3182. * @license
  3183. * Copyright 2020 Google LLC
  3184. *
  3185. * Licensed under the Apache License, Version 2.0 (the "License");
  3186. * you may not use this file except in compliance with the License.
  3187. * You may obtain a copy of the License at
  3188. *
  3189. * http://www.apache.org/licenses/LICENSE-2.0
  3190. *
  3191. * Unless required by applicable law or agreed to in writing, software
  3192. * distributed under the License is distributed on an "AS IS" BASIS,
  3193. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3194. * See the License for the specific language governing permissions and
  3195. * limitations under the License.
  3196. */
  3197. async function signInWithEmailLink$1(auth, request) {
  3198. return _performSignInRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:signInWithEmailLink" /* Endpoint.SIGN_IN_WITH_EMAIL_LINK */, _addTidIfNecessary(auth, request));
  3199. }
  3200. async function signInWithEmailLinkForLinking(auth, request) {
  3201. return _performSignInRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:signInWithEmailLink" /* Endpoint.SIGN_IN_WITH_EMAIL_LINK */, _addTidIfNecessary(auth, request));
  3202. }
  3203. /**
  3204. * @license
  3205. * Copyright 2020 Google LLC
  3206. *
  3207. * Licensed under the Apache License, Version 2.0 (the "License");
  3208. * you may not use this file except in compliance with the License.
  3209. * You may obtain a copy of the License at
  3210. *
  3211. * http://www.apache.org/licenses/LICENSE-2.0
  3212. *
  3213. * Unless required by applicable law or agreed to in writing, software
  3214. * distributed under the License is distributed on an "AS IS" BASIS,
  3215. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3216. * See the License for the specific language governing permissions and
  3217. * limitations under the License.
  3218. */
  3219. /**
  3220. * Interface that represents the credentials returned by {@link EmailAuthProvider} for
  3221. * {@link ProviderId}.PASSWORD
  3222. *
  3223. * @remarks
  3224. * Covers both {@link SignInMethod}.EMAIL_PASSWORD and
  3225. * {@link SignInMethod}.EMAIL_LINK.
  3226. *
  3227. * @public
  3228. */
  3229. class EmailAuthCredential extends AuthCredential {
  3230. /** @internal */
  3231. constructor(
  3232. /** @internal */
  3233. _email,
  3234. /** @internal */
  3235. _password, signInMethod,
  3236. /** @internal */
  3237. _tenantId = null) {
  3238. super("password" /* ProviderId.PASSWORD */, signInMethod);
  3239. this._email = _email;
  3240. this._password = _password;
  3241. this._tenantId = _tenantId;
  3242. }
  3243. /** @internal */
  3244. static _fromEmailAndPassword(email, password) {
  3245. return new EmailAuthCredential(email, password, "password" /* SignInMethod.EMAIL_PASSWORD */);
  3246. }
  3247. /** @internal */
  3248. static _fromEmailAndCode(email, oobCode, tenantId = null) {
  3249. return new EmailAuthCredential(email, oobCode, "emailLink" /* SignInMethod.EMAIL_LINK */, tenantId);
  3250. }
  3251. /** {@inheritdoc AuthCredential.toJSON} */
  3252. toJSON() {
  3253. return {
  3254. email: this._email,
  3255. password: this._password,
  3256. signInMethod: this.signInMethod,
  3257. tenantId: this._tenantId
  3258. };
  3259. }
  3260. /**
  3261. * Static method to deserialize a JSON representation of an object into an {@link AuthCredential}.
  3262. *
  3263. * @param json - Either `object` or the stringified representation of the object. When string is
  3264. * provided, `JSON.parse` would be called first.
  3265. *
  3266. * @returns If the JSON input does not represent an {@link AuthCredential}, null is returned.
  3267. */
  3268. static fromJSON(json) {
  3269. const obj = typeof json === 'string' ? JSON.parse(json) : json;
  3270. if ((obj === null || obj === void 0 ? void 0 : obj.email) && (obj === null || obj === void 0 ? void 0 : obj.password)) {
  3271. if (obj.signInMethod === "password" /* SignInMethod.EMAIL_PASSWORD */) {
  3272. return this._fromEmailAndPassword(obj.email, obj.password);
  3273. }
  3274. else if (obj.signInMethod === "emailLink" /* SignInMethod.EMAIL_LINK */) {
  3275. return this._fromEmailAndCode(obj.email, obj.password, obj.tenantId);
  3276. }
  3277. }
  3278. return null;
  3279. }
  3280. /** @internal */
  3281. async _getIdTokenResponse(auth) {
  3282. var _a;
  3283. switch (this.signInMethod) {
  3284. case "password" /* SignInMethod.EMAIL_PASSWORD */:
  3285. const request = {
  3286. returnSecureToken: true,
  3287. email: this._email,
  3288. password: this._password,
  3289. clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */
  3290. };
  3291. if ((_a = auth._getRecaptchaConfig()) === null || _a === void 0 ? void 0 : _a.emailPasswordEnabled) {
  3292. const requestWithRecaptcha = await injectRecaptchaFields(auth, request, "signInWithPassword" /* RecaptchaActionName.SIGN_IN_WITH_PASSWORD */);
  3293. return signInWithPassword(auth, requestWithRecaptcha);
  3294. }
  3295. else {
  3296. return signInWithPassword(auth, request).catch(async (error) => {
  3297. if (error.code === `auth/${"missing-recaptcha-token" /* AuthErrorCode.MISSING_RECAPTCHA_TOKEN */}`) {
  3298. console.log('Sign-in with email address and password is protected by reCAPTCHA for this project. Automatically triggering the reCAPTCHA flow and restarting the sign-in flow.');
  3299. const requestWithRecaptcha = await injectRecaptchaFields(auth, request, "signInWithPassword" /* RecaptchaActionName.SIGN_IN_WITH_PASSWORD */);
  3300. return signInWithPassword(auth, requestWithRecaptcha);
  3301. }
  3302. else {
  3303. return Promise.reject(error);
  3304. }
  3305. });
  3306. }
  3307. case "emailLink" /* SignInMethod.EMAIL_LINK */:
  3308. return signInWithEmailLink$1(auth, {
  3309. email: this._email,
  3310. oobCode: this._password
  3311. });
  3312. default:
  3313. _fail(auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  3314. }
  3315. }
  3316. /** @internal */
  3317. async _linkToIdToken(auth, idToken) {
  3318. switch (this.signInMethod) {
  3319. case "password" /* SignInMethod.EMAIL_PASSWORD */:
  3320. return updateEmailPassword(auth, {
  3321. idToken,
  3322. returnSecureToken: true,
  3323. email: this._email,
  3324. password: this._password
  3325. });
  3326. case "emailLink" /* SignInMethod.EMAIL_LINK */:
  3327. return signInWithEmailLinkForLinking(auth, {
  3328. idToken,
  3329. email: this._email,
  3330. oobCode: this._password
  3331. });
  3332. default:
  3333. _fail(auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  3334. }
  3335. }
  3336. /** @internal */
  3337. _getReauthenticationResolver(auth) {
  3338. return this._getIdTokenResponse(auth);
  3339. }
  3340. }
  3341. /**
  3342. * @license
  3343. * Copyright 2020 Google LLC
  3344. *
  3345. * Licensed under the Apache License, Version 2.0 (the "License");
  3346. * you may not use this file except in compliance with the License.
  3347. * You may obtain a copy of the License at
  3348. *
  3349. * http://www.apache.org/licenses/LICENSE-2.0
  3350. *
  3351. * Unless required by applicable law or agreed to in writing, software
  3352. * distributed under the License is distributed on an "AS IS" BASIS,
  3353. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3354. * See the License for the specific language governing permissions and
  3355. * limitations under the License.
  3356. */
  3357. async function signInWithIdp(auth, request) {
  3358. return _performSignInRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:signInWithIdp" /* Endpoint.SIGN_IN_WITH_IDP */, _addTidIfNecessary(auth, request));
  3359. }
  3360. /**
  3361. * @license
  3362. * Copyright 2020 Google LLC
  3363. *
  3364. * Licensed under the Apache License, Version 2.0 (the "License");
  3365. * you may not use this file except in compliance with the License.
  3366. * You may obtain a copy of the License at
  3367. *
  3368. * http://www.apache.org/licenses/LICENSE-2.0
  3369. *
  3370. * Unless required by applicable law or agreed to in writing, software
  3371. * distributed under the License is distributed on an "AS IS" BASIS,
  3372. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3373. * See the License for the specific language governing permissions and
  3374. * limitations under the License.
  3375. */
  3376. const IDP_REQUEST_URI$1 = 'http://localhost';
  3377. /**
  3378. * Represents the OAuth credentials returned by an {@link OAuthProvider}.
  3379. *
  3380. * @remarks
  3381. * Implementations specify the details about each auth provider's credential requirements.
  3382. *
  3383. * @public
  3384. */
  3385. class OAuthCredential extends AuthCredential {
  3386. constructor() {
  3387. super(...arguments);
  3388. this.pendingToken = null;
  3389. }
  3390. /** @internal */
  3391. static _fromParams(params) {
  3392. const cred = new OAuthCredential(params.providerId, params.signInMethod);
  3393. if (params.idToken || params.accessToken) {
  3394. // OAuth 2 and either ID token or access token.
  3395. if (params.idToken) {
  3396. cred.idToken = params.idToken;
  3397. }
  3398. if (params.accessToken) {
  3399. cred.accessToken = params.accessToken;
  3400. }
  3401. // Add nonce if available and no pendingToken is present.
  3402. if (params.nonce && !params.pendingToken) {
  3403. cred.nonce = params.nonce;
  3404. }
  3405. if (params.pendingToken) {
  3406. cred.pendingToken = params.pendingToken;
  3407. }
  3408. }
  3409. else if (params.oauthToken && params.oauthTokenSecret) {
  3410. // OAuth 1 and OAuth token with token secret
  3411. cred.accessToken = params.oauthToken;
  3412. cred.secret = params.oauthTokenSecret;
  3413. }
  3414. else {
  3415. _fail("argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  3416. }
  3417. return cred;
  3418. }
  3419. /** {@inheritdoc AuthCredential.toJSON} */
  3420. toJSON() {
  3421. return {
  3422. idToken: this.idToken,
  3423. accessToken: this.accessToken,
  3424. secret: this.secret,
  3425. nonce: this.nonce,
  3426. pendingToken: this.pendingToken,
  3427. providerId: this.providerId,
  3428. signInMethod: this.signInMethod
  3429. };
  3430. }
  3431. /**
  3432. * Static method to deserialize a JSON representation of an object into an
  3433. * {@link AuthCredential}.
  3434. *
  3435. * @param json - Input can be either Object or the stringified representation of the object.
  3436. * When string is provided, JSON.parse would be called first.
  3437. *
  3438. * @returns If the JSON input does not represent an {@link AuthCredential}, null is returned.
  3439. */
  3440. static fromJSON(json) {
  3441. const obj = typeof json === 'string' ? JSON.parse(json) : json;
  3442. const { providerId, signInMethod } = obj, rest = tslib.__rest(obj, ["providerId", "signInMethod"]);
  3443. if (!providerId || !signInMethod) {
  3444. return null;
  3445. }
  3446. const cred = new OAuthCredential(providerId, signInMethod);
  3447. cred.idToken = rest.idToken || undefined;
  3448. cred.accessToken = rest.accessToken || undefined;
  3449. cred.secret = rest.secret;
  3450. cred.nonce = rest.nonce;
  3451. cred.pendingToken = rest.pendingToken || null;
  3452. return cred;
  3453. }
  3454. /** @internal */
  3455. _getIdTokenResponse(auth) {
  3456. const request = this.buildRequest();
  3457. return signInWithIdp(auth, request);
  3458. }
  3459. /** @internal */
  3460. _linkToIdToken(auth, idToken) {
  3461. const request = this.buildRequest();
  3462. request.idToken = idToken;
  3463. return signInWithIdp(auth, request);
  3464. }
  3465. /** @internal */
  3466. _getReauthenticationResolver(auth) {
  3467. const request = this.buildRequest();
  3468. request.autoCreate = false;
  3469. return signInWithIdp(auth, request);
  3470. }
  3471. buildRequest() {
  3472. const request = {
  3473. requestUri: IDP_REQUEST_URI$1,
  3474. returnSecureToken: true
  3475. };
  3476. if (this.pendingToken) {
  3477. request.pendingToken = this.pendingToken;
  3478. }
  3479. else {
  3480. const postBody = {};
  3481. if (this.idToken) {
  3482. postBody['id_token'] = this.idToken;
  3483. }
  3484. if (this.accessToken) {
  3485. postBody['access_token'] = this.accessToken;
  3486. }
  3487. if (this.secret) {
  3488. postBody['oauth_token_secret'] = this.secret;
  3489. }
  3490. postBody['providerId'] = this.providerId;
  3491. if (this.nonce && !this.pendingToken) {
  3492. postBody['nonce'] = this.nonce;
  3493. }
  3494. request.postBody = util.querystring(postBody);
  3495. }
  3496. return request;
  3497. }
  3498. }
  3499. /**
  3500. * @license
  3501. * Copyright 2020 Google LLC
  3502. *
  3503. * Licensed under the Apache License, Version 2.0 (the "License");
  3504. * you may not use this file except in compliance with the License.
  3505. * You may obtain a copy of the License at
  3506. *
  3507. * http://www.apache.org/licenses/LICENSE-2.0
  3508. *
  3509. * Unless required by applicable law or agreed to in writing, software
  3510. * distributed under the License is distributed on an "AS IS" BASIS,
  3511. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3512. * See the License for the specific language governing permissions and
  3513. * limitations under the License.
  3514. */
  3515. async function sendPhoneVerificationCode(auth, request) {
  3516. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:sendVerificationCode" /* Endpoint.SEND_VERIFICATION_CODE */, _addTidIfNecessary(auth, request));
  3517. }
  3518. async function signInWithPhoneNumber$1(auth, request) {
  3519. return _performSignInRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:signInWithPhoneNumber" /* Endpoint.SIGN_IN_WITH_PHONE_NUMBER */, _addTidIfNecessary(auth, request));
  3520. }
  3521. async function linkWithPhoneNumber$1(auth, request) {
  3522. const response = await _performSignInRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:signInWithPhoneNumber" /* Endpoint.SIGN_IN_WITH_PHONE_NUMBER */, _addTidIfNecessary(auth, request));
  3523. if (response.temporaryProof) {
  3524. throw _makeTaggedError(auth, "account-exists-with-different-credential" /* AuthErrorCode.NEED_CONFIRMATION */, response);
  3525. }
  3526. return response;
  3527. }
  3528. const VERIFY_PHONE_NUMBER_FOR_EXISTING_ERROR_MAP_ = {
  3529. ["USER_NOT_FOUND" /* ServerError.USER_NOT_FOUND */]: "user-not-found" /* AuthErrorCode.USER_DELETED */
  3530. };
  3531. async function verifyPhoneNumberForExisting(auth, request) {
  3532. const apiRequest = Object.assign(Object.assign({}, request), { operation: 'REAUTH' });
  3533. return _performSignInRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:signInWithPhoneNumber" /* Endpoint.SIGN_IN_WITH_PHONE_NUMBER */, _addTidIfNecessary(auth, apiRequest), VERIFY_PHONE_NUMBER_FOR_EXISTING_ERROR_MAP_);
  3534. }
  3535. /**
  3536. * @license
  3537. * Copyright 2020 Google LLC
  3538. *
  3539. * Licensed under the Apache License, Version 2.0 (the "License");
  3540. * you may not use this file except in compliance with the License.
  3541. * You may obtain a copy of the License at
  3542. *
  3543. * http://www.apache.org/licenses/LICENSE-2.0
  3544. *
  3545. * Unless required by applicable law or agreed to in writing, software
  3546. * distributed under the License is distributed on an "AS IS" BASIS,
  3547. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3548. * See the License for the specific language governing permissions and
  3549. * limitations under the License.
  3550. */
  3551. /**
  3552. * Represents the credentials returned by {@link PhoneAuthProvider}.
  3553. *
  3554. * @public
  3555. */
  3556. class PhoneAuthCredential extends AuthCredential {
  3557. constructor(params) {
  3558. super("phone" /* ProviderId.PHONE */, "phone" /* SignInMethod.PHONE */);
  3559. this.params = params;
  3560. }
  3561. /** @internal */
  3562. static _fromVerification(verificationId, verificationCode) {
  3563. return new PhoneAuthCredential({ verificationId, verificationCode });
  3564. }
  3565. /** @internal */
  3566. static _fromTokenResponse(phoneNumber, temporaryProof) {
  3567. return new PhoneAuthCredential({ phoneNumber, temporaryProof });
  3568. }
  3569. /** @internal */
  3570. _getIdTokenResponse(auth) {
  3571. return signInWithPhoneNumber$1(auth, this._makeVerificationRequest());
  3572. }
  3573. /** @internal */
  3574. _linkToIdToken(auth, idToken) {
  3575. return linkWithPhoneNumber$1(auth, Object.assign({ idToken }, this._makeVerificationRequest()));
  3576. }
  3577. /** @internal */
  3578. _getReauthenticationResolver(auth) {
  3579. return verifyPhoneNumberForExisting(auth, this._makeVerificationRequest());
  3580. }
  3581. /** @internal */
  3582. _makeVerificationRequest() {
  3583. const { temporaryProof, phoneNumber, verificationId, verificationCode } = this.params;
  3584. if (temporaryProof && phoneNumber) {
  3585. return { temporaryProof, phoneNumber };
  3586. }
  3587. return {
  3588. sessionInfo: verificationId,
  3589. code: verificationCode
  3590. };
  3591. }
  3592. /** {@inheritdoc AuthCredential.toJSON} */
  3593. toJSON() {
  3594. const obj = {
  3595. providerId: this.providerId
  3596. };
  3597. if (this.params.phoneNumber) {
  3598. obj.phoneNumber = this.params.phoneNumber;
  3599. }
  3600. if (this.params.temporaryProof) {
  3601. obj.temporaryProof = this.params.temporaryProof;
  3602. }
  3603. if (this.params.verificationCode) {
  3604. obj.verificationCode = this.params.verificationCode;
  3605. }
  3606. if (this.params.verificationId) {
  3607. obj.verificationId = this.params.verificationId;
  3608. }
  3609. return obj;
  3610. }
  3611. /** Generates a phone credential based on a plain object or a JSON string. */
  3612. static fromJSON(json) {
  3613. if (typeof json === 'string') {
  3614. json = JSON.parse(json);
  3615. }
  3616. const { verificationId, verificationCode, phoneNumber, temporaryProof } = json;
  3617. if (!verificationCode &&
  3618. !verificationId &&
  3619. !phoneNumber &&
  3620. !temporaryProof) {
  3621. return null;
  3622. }
  3623. return new PhoneAuthCredential({
  3624. verificationId,
  3625. verificationCode,
  3626. phoneNumber,
  3627. temporaryProof
  3628. });
  3629. }
  3630. }
  3631. /**
  3632. * @license
  3633. * Copyright 2020 Google LLC
  3634. *
  3635. * Licensed under the Apache License, Version 2.0 (the "License");
  3636. * you may not use this file except in compliance with the License.
  3637. * You may obtain a copy of the License at
  3638. *
  3639. * http://www.apache.org/licenses/LICENSE-2.0
  3640. *
  3641. * Unless required by applicable law or agreed to in writing, software
  3642. * distributed under the License is distributed on an "AS IS" BASIS,
  3643. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3644. * See the License for the specific language governing permissions and
  3645. * limitations under the License.
  3646. */
  3647. /**
  3648. * Maps the mode string in action code URL to Action Code Info operation.
  3649. *
  3650. * @param mode
  3651. */
  3652. function parseMode(mode) {
  3653. switch (mode) {
  3654. case 'recoverEmail':
  3655. return "RECOVER_EMAIL" /* ActionCodeOperation.RECOVER_EMAIL */;
  3656. case 'resetPassword':
  3657. return "PASSWORD_RESET" /* ActionCodeOperation.PASSWORD_RESET */;
  3658. case 'signIn':
  3659. return "EMAIL_SIGNIN" /* ActionCodeOperation.EMAIL_SIGNIN */;
  3660. case 'verifyEmail':
  3661. return "VERIFY_EMAIL" /* ActionCodeOperation.VERIFY_EMAIL */;
  3662. case 'verifyAndChangeEmail':
  3663. return "VERIFY_AND_CHANGE_EMAIL" /* ActionCodeOperation.VERIFY_AND_CHANGE_EMAIL */;
  3664. case 'revertSecondFactorAddition':
  3665. return "REVERT_SECOND_FACTOR_ADDITION" /* ActionCodeOperation.REVERT_SECOND_FACTOR_ADDITION */;
  3666. default:
  3667. return null;
  3668. }
  3669. }
  3670. /**
  3671. * Helper to parse FDL links
  3672. *
  3673. * @param url
  3674. */
  3675. function parseDeepLink(url) {
  3676. const link = util.querystringDecode(util.extractQuerystring(url))['link'];
  3677. // Double link case (automatic redirect).
  3678. const doubleDeepLink = link
  3679. ? util.querystringDecode(util.extractQuerystring(link))['deep_link_id']
  3680. : null;
  3681. // iOS custom scheme links.
  3682. const iOSDeepLink = util.querystringDecode(util.extractQuerystring(url))['deep_link_id'];
  3683. const iOSDoubleDeepLink = iOSDeepLink
  3684. ? util.querystringDecode(util.extractQuerystring(iOSDeepLink))['link']
  3685. : null;
  3686. return iOSDoubleDeepLink || iOSDeepLink || doubleDeepLink || link || url;
  3687. }
  3688. /**
  3689. * A utility class to parse email action URLs such as password reset, email verification,
  3690. * email link sign in, etc.
  3691. *
  3692. * @public
  3693. */
  3694. class ActionCodeURL {
  3695. /**
  3696. * @param actionLink - The link from which to extract the URL.
  3697. * @returns The {@link ActionCodeURL} object, or null if the link is invalid.
  3698. *
  3699. * @internal
  3700. */
  3701. constructor(actionLink) {
  3702. var _a, _b, _c, _d, _e, _f;
  3703. const searchParams = util.querystringDecode(util.extractQuerystring(actionLink));
  3704. const apiKey = (_a = searchParams["apiKey" /* QueryField.API_KEY */]) !== null && _a !== void 0 ? _a : null;
  3705. const code = (_b = searchParams["oobCode" /* QueryField.CODE */]) !== null && _b !== void 0 ? _b : null;
  3706. const operation = parseMode((_c = searchParams["mode" /* QueryField.MODE */]) !== null && _c !== void 0 ? _c : null);
  3707. // Validate API key, code and mode.
  3708. _assert(apiKey && code && operation, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  3709. this.apiKey = apiKey;
  3710. this.operation = operation;
  3711. this.code = code;
  3712. this.continueUrl = (_d = searchParams["continueUrl" /* QueryField.CONTINUE_URL */]) !== null && _d !== void 0 ? _d : null;
  3713. this.languageCode = (_e = searchParams["languageCode" /* QueryField.LANGUAGE_CODE */]) !== null && _e !== void 0 ? _e : null;
  3714. this.tenantId = (_f = searchParams["tenantId" /* QueryField.TENANT_ID */]) !== null && _f !== void 0 ? _f : null;
  3715. }
  3716. /**
  3717. * Parses the email action link string and returns an {@link ActionCodeURL} if the link is valid,
  3718. * otherwise returns null.
  3719. *
  3720. * @param link - The email action link string.
  3721. * @returns The {@link ActionCodeURL} object, or null if the link is invalid.
  3722. *
  3723. * @public
  3724. */
  3725. static parseLink(link) {
  3726. const actionLink = parseDeepLink(link);
  3727. try {
  3728. return new ActionCodeURL(actionLink);
  3729. }
  3730. catch (_a) {
  3731. return null;
  3732. }
  3733. }
  3734. }
  3735. /**
  3736. * Parses the email action link string and returns an {@link ActionCodeURL} if
  3737. * the link is valid, otherwise returns null.
  3738. *
  3739. * @public
  3740. */
  3741. function parseActionCodeURL(link) {
  3742. return ActionCodeURL.parseLink(link);
  3743. }
  3744. /**
  3745. * @license
  3746. * Copyright 2020 Google LLC
  3747. *
  3748. * Licensed under the Apache License, Version 2.0 (the "License");
  3749. * you may not use this file except in compliance with the License.
  3750. * You may obtain a copy of the License at
  3751. *
  3752. * http://www.apache.org/licenses/LICENSE-2.0
  3753. *
  3754. * Unless required by applicable law or agreed to in writing, software
  3755. * distributed under the License is distributed on an "AS IS" BASIS,
  3756. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3757. * See the License for the specific language governing permissions and
  3758. * limitations under the License.
  3759. */
  3760. /**
  3761. * Provider for generating {@link EmailAuthCredential}.
  3762. *
  3763. * @public
  3764. */
  3765. class EmailAuthProvider {
  3766. constructor() {
  3767. /**
  3768. * Always set to {@link ProviderId}.PASSWORD, even for email link.
  3769. */
  3770. this.providerId = EmailAuthProvider.PROVIDER_ID;
  3771. }
  3772. /**
  3773. * Initialize an {@link AuthCredential} using an email and password.
  3774. *
  3775. * @example
  3776. * ```javascript
  3777. * const authCredential = EmailAuthProvider.credential(email, password);
  3778. * const userCredential = await signInWithCredential(auth, authCredential);
  3779. * ```
  3780. *
  3781. * @example
  3782. * ```javascript
  3783. * const userCredential = await signInWithEmailAndPassword(auth, email, password);
  3784. * ```
  3785. *
  3786. * @param email - Email address.
  3787. * @param password - User account password.
  3788. * @returns The auth provider credential.
  3789. */
  3790. static credential(email, password) {
  3791. return EmailAuthCredential._fromEmailAndPassword(email, password);
  3792. }
  3793. /**
  3794. * Initialize an {@link AuthCredential} using an email and an email link after a sign in with
  3795. * email link operation.
  3796. *
  3797. * @example
  3798. * ```javascript
  3799. * const authCredential = EmailAuthProvider.credentialWithLink(auth, email, emailLink);
  3800. * const userCredential = await signInWithCredential(auth, authCredential);
  3801. * ```
  3802. *
  3803. * @example
  3804. * ```javascript
  3805. * await sendSignInLinkToEmail(auth, email);
  3806. * // Obtain emailLink from user.
  3807. * const userCredential = await signInWithEmailLink(auth, email, emailLink);
  3808. * ```
  3809. *
  3810. * @param auth - The {@link Auth} instance used to verify the link.
  3811. * @param email - Email address.
  3812. * @param emailLink - Sign-in email link.
  3813. * @returns - The auth provider credential.
  3814. */
  3815. static credentialWithLink(email, emailLink) {
  3816. const actionCodeUrl = ActionCodeURL.parseLink(emailLink);
  3817. _assert(actionCodeUrl, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  3818. return EmailAuthCredential._fromEmailAndCode(email, actionCodeUrl.code, actionCodeUrl.tenantId);
  3819. }
  3820. }
  3821. /**
  3822. * Always set to {@link ProviderId}.PASSWORD, even for email link.
  3823. */
  3824. EmailAuthProvider.PROVIDER_ID = "password" /* ProviderId.PASSWORD */;
  3825. /**
  3826. * Always set to {@link SignInMethod}.EMAIL_PASSWORD.
  3827. */
  3828. EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD = "password" /* SignInMethod.EMAIL_PASSWORD */;
  3829. /**
  3830. * Always set to {@link SignInMethod}.EMAIL_LINK.
  3831. */
  3832. EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD = "emailLink" /* SignInMethod.EMAIL_LINK */;
  3833. /**
  3834. * @license
  3835. * Copyright 2020 Google LLC
  3836. *
  3837. * Licensed under the Apache License, Version 2.0 (the "License");
  3838. * you may not use this file except in compliance with the License.
  3839. * You may obtain a copy of the License at
  3840. *
  3841. * http://www.apache.org/licenses/LICENSE-2.0
  3842. *
  3843. * Unless required by applicable law or agreed to in writing, software
  3844. * distributed under the License is distributed on an "AS IS" BASIS,
  3845. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3846. * See the License for the specific language governing permissions and
  3847. * limitations under the License.
  3848. */
  3849. /**
  3850. * The base class for all Federated providers (OAuth (including OIDC), SAML).
  3851. *
  3852. * This class is not meant to be instantiated directly.
  3853. *
  3854. * @public
  3855. */
  3856. class FederatedAuthProvider {
  3857. /**
  3858. * Constructor for generic OAuth providers.
  3859. *
  3860. * @param providerId - Provider for which credentials should be generated.
  3861. */
  3862. constructor(providerId) {
  3863. this.providerId = providerId;
  3864. /** @internal */
  3865. this.defaultLanguageCode = null;
  3866. /** @internal */
  3867. this.customParameters = {};
  3868. }
  3869. /**
  3870. * Set the language gode.
  3871. *
  3872. * @param languageCode - language code
  3873. */
  3874. setDefaultLanguage(languageCode) {
  3875. this.defaultLanguageCode = languageCode;
  3876. }
  3877. /**
  3878. * Sets the OAuth custom parameters to pass in an OAuth request for popup and redirect sign-in
  3879. * operations.
  3880. *
  3881. * @remarks
  3882. * For a detailed list, check the reserved required OAuth 2.0 parameters such as `client_id`,
  3883. * `redirect_uri`, `scope`, `response_type`, and `state` are not allowed and will be ignored.
  3884. *
  3885. * @param customOAuthParameters - The custom OAuth parameters to pass in the OAuth request.
  3886. */
  3887. setCustomParameters(customOAuthParameters) {
  3888. this.customParameters = customOAuthParameters;
  3889. return this;
  3890. }
  3891. /**
  3892. * Retrieve the current list of {@link CustomParameters}.
  3893. */
  3894. getCustomParameters() {
  3895. return this.customParameters;
  3896. }
  3897. }
  3898. /**
  3899. * @license
  3900. * Copyright 2019 Google LLC
  3901. *
  3902. * Licensed under the Apache License, Version 2.0 (the "License");
  3903. * you may not use this file except in compliance with the License.
  3904. * You may obtain a copy of the License at
  3905. *
  3906. * http://www.apache.org/licenses/LICENSE-2.0
  3907. *
  3908. * Unless required by applicable law or agreed to in writing, software
  3909. * distributed under the License is distributed on an "AS IS" BASIS,
  3910. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3911. * See the License for the specific language governing permissions and
  3912. * limitations under the License.
  3913. */
  3914. /**
  3915. * Common code to all OAuth providers. This is separate from the
  3916. * {@link OAuthProvider} so that child providers (like
  3917. * {@link GoogleAuthProvider}) don't inherit the `credential` instance method.
  3918. * Instead, they rely on a static `credential` method.
  3919. */
  3920. class BaseOAuthProvider extends FederatedAuthProvider {
  3921. constructor() {
  3922. super(...arguments);
  3923. /** @internal */
  3924. this.scopes = [];
  3925. }
  3926. /**
  3927. * Add an OAuth scope to the credential.
  3928. *
  3929. * @param scope - Provider OAuth scope to add.
  3930. */
  3931. addScope(scope) {
  3932. // If not already added, add scope to list.
  3933. if (!this.scopes.includes(scope)) {
  3934. this.scopes.push(scope);
  3935. }
  3936. return this;
  3937. }
  3938. /**
  3939. * Retrieve the current list of OAuth scopes.
  3940. */
  3941. getScopes() {
  3942. return [...this.scopes];
  3943. }
  3944. }
  3945. /**
  3946. * Provider for generating generic {@link OAuthCredential}.
  3947. *
  3948. * @example
  3949. * ```javascript
  3950. * // Sign in using a redirect.
  3951. * const provider = new OAuthProvider('google.com');
  3952. * // Start a sign in process for an unauthenticated user.
  3953. * provider.addScope('profile');
  3954. * provider.addScope('email');
  3955. * await signInWithRedirect(auth, provider);
  3956. * // This will trigger a full page redirect away from your app
  3957. *
  3958. * // After returning from the redirect when your app initializes you can obtain the result
  3959. * const result = await getRedirectResult(auth);
  3960. * if (result) {
  3961. * // This is the signed-in user
  3962. * const user = result.user;
  3963. * // This gives you a OAuth Access Token for the provider.
  3964. * const credential = provider.credentialFromResult(auth, result);
  3965. * const token = credential.accessToken;
  3966. * }
  3967. * ```
  3968. *
  3969. * @example
  3970. * ```javascript
  3971. * // Sign in using a popup.
  3972. * const provider = new OAuthProvider('google.com');
  3973. * provider.addScope('profile');
  3974. * provider.addScope('email');
  3975. * const result = await signInWithPopup(auth, provider);
  3976. *
  3977. * // The signed-in user info.
  3978. * const user = result.user;
  3979. * // This gives you a OAuth Access Token for the provider.
  3980. * const credential = provider.credentialFromResult(auth, result);
  3981. * const token = credential.accessToken;
  3982. * ```
  3983. * @public
  3984. */
  3985. class OAuthProvider extends BaseOAuthProvider {
  3986. /**
  3987. * Creates an {@link OAuthCredential} from a JSON string or a plain object.
  3988. * @param json - A plain object or a JSON string
  3989. */
  3990. static credentialFromJSON(json) {
  3991. const obj = typeof json === 'string' ? JSON.parse(json) : json;
  3992. _assert('providerId' in obj && 'signInMethod' in obj, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  3993. return OAuthCredential._fromParams(obj);
  3994. }
  3995. /**
  3996. * Creates a {@link OAuthCredential} from a generic OAuth provider's access token or ID token.
  3997. *
  3998. * @remarks
  3999. * The raw nonce is required when an ID token with a nonce field is provided. The SHA-256 hash of
  4000. * the raw nonce must match the nonce field in the ID token.
  4001. *
  4002. * @example
  4003. * ```javascript
  4004. * // `googleUser` from the onsuccess Google Sign In callback.
  4005. * // Initialize a generate OAuth provider with a `google.com` providerId.
  4006. * const provider = new OAuthProvider('google.com');
  4007. * const credential = provider.credential({
  4008. * idToken: googleUser.getAuthResponse().id_token,
  4009. * });
  4010. * const result = await signInWithCredential(credential);
  4011. * ```
  4012. *
  4013. * @param params - Either the options object containing the ID token, access token and raw nonce
  4014. * or the ID token string.
  4015. */
  4016. credential(params) {
  4017. return this._credential(Object.assign(Object.assign({}, params), { nonce: params.rawNonce }));
  4018. }
  4019. /** An internal credential method that accepts more permissive options */
  4020. _credential(params) {
  4021. _assert(params.idToken || params.accessToken, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  4022. // For OAuthCredential, sign in method is same as providerId.
  4023. return OAuthCredential._fromParams(Object.assign(Object.assign({}, params), { providerId: this.providerId, signInMethod: this.providerId }));
  4024. }
  4025. /**
  4026. * Used to extract the underlying {@link OAuthCredential} from a {@link UserCredential}.
  4027. *
  4028. * @param userCredential - The user credential.
  4029. */
  4030. static credentialFromResult(userCredential) {
  4031. return OAuthProvider.oauthCredentialFromTaggedObject(userCredential);
  4032. }
  4033. /**
  4034. * Used to extract the underlying {@link OAuthCredential} from a {@link AuthError} which was
  4035. * thrown during a sign-in, link, or reauthenticate operation.
  4036. *
  4037. * @param userCredential - The user credential.
  4038. */
  4039. static credentialFromError(error) {
  4040. return OAuthProvider.oauthCredentialFromTaggedObject((error.customData || {}));
  4041. }
  4042. static oauthCredentialFromTaggedObject({ _tokenResponse: tokenResponse }) {
  4043. if (!tokenResponse) {
  4044. return null;
  4045. }
  4046. const { oauthIdToken, oauthAccessToken, oauthTokenSecret, pendingToken, nonce, providerId } = tokenResponse;
  4047. if (!oauthAccessToken &&
  4048. !oauthTokenSecret &&
  4049. !oauthIdToken &&
  4050. !pendingToken) {
  4051. return null;
  4052. }
  4053. if (!providerId) {
  4054. return null;
  4055. }
  4056. try {
  4057. return new OAuthProvider(providerId)._credential({
  4058. idToken: oauthIdToken,
  4059. accessToken: oauthAccessToken,
  4060. nonce,
  4061. pendingToken
  4062. });
  4063. }
  4064. catch (e) {
  4065. return null;
  4066. }
  4067. }
  4068. }
  4069. /**
  4070. * @license
  4071. * Copyright 2020 Google LLC
  4072. *
  4073. * Licensed under the Apache License, Version 2.0 (the "License");
  4074. * you may not use this file except in compliance with the License.
  4075. * You may obtain a copy of the License at
  4076. *
  4077. * http://www.apache.org/licenses/LICENSE-2.0
  4078. *
  4079. * Unless required by applicable law or agreed to in writing, software
  4080. * distributed under the License is distributed on an "AS IS" BASIS,
  4081. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4082. * See the License for the specific language governing permissions and
  4083. * limitations under the License.
  4084. */
  4085. /**
  4086. * Provider for generating an {@link OAuthCredential} for {@link ProviderId}.FACEBOOK.
  4087. *
  4088. * @example
  4089. * ```javascript
  4090. * // Sign in using a redirect.
  4091. * const provider = new FacebookAuthProvider();
  4092. * // Start a sign in process for an unauthenticated user.
  4093. * provider.addScope('user_birthday');
  4094. * await signInWithRedirect(auth, provider);
  4095. * // This will trigger a full page redirect away from your app
  4096. *
  4097. * // After returning from the redirect when your app initializes you can obtain the result
  4098. * const result = await getRedirectResult(auth);
  4099. * if (result) {
  4100. * // This is the signed-in user
  4101. * const user = result.user;
  4102. * // This gives you a Facebook Access Token.
  4103. * const credential = FacebookAuthProvider.credentialFromResult(result);
  4104. * const token = credential.accessToken;
  4105. * }
  4106. * ```
  4107. *
  4108. * @example
  4109. * ```javascript
  4110. * // Sign in using a popup.
  4111. * const provider = new FacebookAuthProvider();
  4112. * provider.addScope('user_birthday');
  4113. * const result = await signInWithPopup(auth, provider);
  4114. *
  4115. * // The signed-in user info.
  4116. * const user = result.user;
  4117. * // This gives you a Facebook Access Token.
  4118. * const credential = FacebookAuthProvider.credentialFromResult(result);
  4119. * const token = credential.accessToken;
  4120. * ```
  4121. *
  4122. * @public
  4123. */
  4124. class FacebookAuthProvider extends BaseOAuthProvider {
  4125. constructor() {
  4126. super("facebook.com" /* ProviderId.FACEBOOK */);
  4127. }
  4128. /**
  4129. * Creates a credential for Facebook.
  4130. *
  4131. * @example
  4132. * ```javascript
  4133. * // `event` from the Facebook auth.authResponseChange callback.
  4134. * const credential = FacebookAuthProvider.credential(event.authResponse.accessToken);
  4135. * const result = await signInWithCredential(credential);
  4136. * ```
  4137. *
  4138. * @param accessToken - Facebook access token.
  4139. */
  4140. static credential(accessToken) {
  4141. return OAuthCredential._fromParams({
  4142. providerId: FacebookAuthProvider.PROVIDER_ID,
  4143. signInMethod: FacebookAuthProvider.FACEBOOK_SIGN_IN_METHOD,
  4144. accessToken
  4145. });
  4146. }
  4147. /**
  4148. * Used to extract the underlying {@link OAuthCredential} from a {@link UserCredential}.
  4149. *
  4150. * @param userCredential - The user credential.
  4151. */
  4152. static credentialFromResult(userCredential) {
  4153. return FacebookAuthProvider.credentialFromTaggedObject(userCredential);
  4154. }
  4155. /**
  4156. * Used to extract the underlying {@link OAuthCredential} from a {@link AuthError} which was
  4157. * thrown during a sign-in, link, or reauthenticate operation.
  4158. *
  4159. * @param userCredential - The user credential.
  4160. */
  4161. static credentialFromError(error) {
  4162. return FacebookAuthProvider.credentialFromTaggedObject((error.customData || {}));
  4163. }
  4164. static credentialFromTaggedObject({ _tokenResponse: tokenResponse }) {
  4165. if (!tokenResponse || !('oauthAccessToken' in tokenResponse)) {
  4166. return null;
  4167. }
  4168. if (!tokenResponse.oauthAccessToken) {
  4169. return null;
  4170. }
  4171. try {
  4172. return FacebookAuthProvider.credential(tokenResponse.oauthAccessToken);
  4173. }
  4174. catch (_a) {
  4175. return null;
  4176. }
  4177. }
  4178. }
  4179. /** Always set to {@link SignInMethod}.FACEBOOK. */
  4180. FacebookAuthProvider.FACEBOOK_SIGN_IN_METHOD = "facebook.com" /* SignInMethod.FACEBOOK */;
  4181. /** Always set to {@link ProviderId}.FACEBOOK. */
  4182. FacebookAuthProvider.PROVIDER_ID = "facebook.com" /* ProviderId.FACEBOOK */;
  4183. /**
  4184. * @license
  4185. * Copyright 2020 Google LLC
  4186. *
  4187. * Licensed under the Apache License, Version 2.0 (the "License");
  4188. * you may not use this file except in compliance with the License.
  4189. * You may obtain a copy of the License at
  4190. *
  4191. * http://www.apache.org/licenses/LICENSE-2.0
  4192. *
  4193. * Unless required by applicable law or agreed to in writing, software
  4194. * distributed under the License is distributed on an "AS IS" BASIS,
  4195. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4196. * See the License for the specific language governing permissions and
  4197. * limitations under the License.
  4198. */
  4199. /**
  4200. * Provider for generating an an {@link OAuthCredential} for {@link ProviderId}.GOOGLE.
  4201. *
  4202. * @example
  4203. * ```javascript
  4204. * // Sign in using a redirect.
  4205. * const provider = new GoogleAuthProvider();
  4206. * // Start a sign in process for an unauthenticated user.
  4207. * provider.addScope('profile');
  4208. * provider.addScope('email');
  4209. * await signInWithRedirect(auth, provider);
  4210. * // This will trigger a full page redirect away from your app
  4211. *
  4212. * // After returning from the redirect when your app initializes you can obtain the result
  4213. * const result = await getRedirectResult(auth);
  4214. * if (result) {
  4215. * // This is the signed-in user
  4216. * const user = result.user;
  4217. * // This gives you a Google Access Token.
  4218. * const credential = GoogleAuthProvider.credentialFromResult(result);
  4219. * const token = credential.accessToken;
  4220. * }
  4221. * ```
  4222. *
  4223. * @example
  4224. * ```javascript
  4225. * // Sign in using a popup.
  4226. * const provider = new GoogleAuthProvider();
  4227. * provider.addScope('profile');
  4228. * provider.addScope('email');
  4229. * const result = await signInWithPopup(auth, provider);
  4230. *
  4231. * // The signed-in user info.
  4232. * const user = result.user;
  4233. * // This gives you a Google Access Token.
  4234. * const credential = GoogleAuthProvider.credentialFromResult(result);
  4235. * const token = credential.accessToken;
  4236. * ```
  4237. *
  4238. * @public
  4239. */
  4240. class GoogleAuthProvider extends BaseOAuthProvider {
  4241. constructor() {
  4242. super("google.com" /* ProviderId.GOOGLE */);
  4243. this.addScope('profile');
  4244. }
  4245. /**
  4246. * Creates a credential for Google. At least one of ID token and access token is required.
  4247. *
  4248. * @example
  4249. * ```javascript
  4250. * // \`googleUser\` from the onsuccess Google Sign In callback.
  4251. * const credential = GoogleAuthProvider.credential(googleUser.getAuthResponse().id_token);
  4252. * const result = await signInWithCredential(credential);
  4253. * ```
  4254. *
  4255. * @param idToken - Google ID token.
  4256. * @param accessToken - Google access token.
  4257. */
  4258. static credential(idToken, accessToken) {
  4259. return OAuthCredential._fromParams({
  4260. providerId: GoogleAuthProvider.PROVIDER_ID,
  4261. signInMethod: GoogleAuthProvider.GOOGLE_SIGN_IN_METHOD,
  4262. idToken,
  4263. accessToken
  4264. });
  4265. }
  4266. /**
  4267. * Used to extract the underlying {@link OAuthCredential} from a {@link UserCredential}.
  4268. *
  4269. * @param userCredential - The user credential.
  4270. */
  4271. static credentialFromResult(userCredential) {
  4272. return GoogleAuthProvider.credentialFromTaggedObject(userCredential);
  4273. }
  4274. /**
  4275. * Used to extract the underlying {@link OAuthCredential} from a {@link AuthError} which was
  4276. * thrown during a sign-in, link, or reauthenticate operation.
  4277. *
  4278. * @param userCredential - The user credential.
  4279. */
  4280. static credentialFromError(error) {
  4281. return GoogleAuthProvider.credentialFromTaggedObject((error.customData || {}));
  4282. }
  4283. static credentialFromTaggedObject({ _tokenResponse: tokenResponse }) {
  4284. if (!tokenResponse) {
  4285. return null;
  4286. }
  4287. const { oauthIdToken, oauthAccessToken } = tokenResponse;
  4288. if (!oauthIdToken && !oauthAccessToken) {
  4289. // This could be an oauth 1 credential or a phone credential
  4290. return null;
  4291. }
  4292. try {
  4293. return GoogleAuthProvider.credential(oauthIdToken, oauthAccessToken);
  4294. }
  4295. catch (_a) {
  4296. return null;
  4297. }
  4298. }
  4299. }
  4300. /** Always set to {@link SignInMethod}.GOOGLE. */
  4301. GoogleAuthProvider.GOOGLE_SIGN_IN_METHOD = "google.com" /* SignInMethod.GOOGLE */;
  4302. /** Always set to {@link ProviderId}.GOOGLE. */
  4303. GoogleAuthProvider.PROVIDER_ID = "google.com" /* ProviderId.GOOGLE */;
  4304. /**
  4305. * @license
  4306. * Copyright 2020 Google LLC
  4307. *
  4308. * Licensed under the Apache License, Version 2.0 (the "License");
  4309. * you may not use this file except in compliance with the License.
  4310. * You may obtain a copy of the License at
  4311. *
  4312. * http://www.apache.org/licenses/LICENSE-2.0
  4313. *
  4314. * Unless required by applicable law or agreed to in writing, software
  4315. * distributed under the License is distributed on an "AS IS" BASIS,
  4316. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4317. * See the License for the specific language governing permissions and
  4318. * limitations under the License.
  4319. */
  4320. /**
  4321. * Provider for generating an {@link OAuthCredential} for {@link ProviderId}.GITHUB.
  4322. *
  4323. * @remarks
  4324. * GitHub requires an OAuth 2.0 redirect, so you can either handle the redirect directly, or use
  4325. * the {@link signInWithPopup} handler:
  4326. *
  4327. * @example
  4328. * ```javascript
  4329. * // Sign in using a redirect.
  4330. * const provider = new GithubAuthProvider();
  4331. * // Start a sign in process for an unauthenticated user.
  4332. * provider.addScope('repo');
  4333. * await signInWithRedirect(auth, provider);
  4334. * // This will trigger a full page redirect away from your app
  4335. *
  4336. * // After returning from the redirect when your app initializes you can obtain the result
  4337. * const result = await getRedirectResult(auth);
  4338. * if (result) {
  4339. * // This is the signed-in user
  4340. * const user = result.user;
  4341. * // This gives you a Github Access Token.
  4342. * const credential = GithubAuthProvider.credentialFromResult(result);
  4343. * const token = credential.accessToken;
  4344. * }
  4345. * ```
  4346. *
  4347. * @example
  4348. * ```javascript
  4349. * // Sign in using a popup.
  4350. * const provider = new GithubAuthProvider();
  4351. * provider.addScope('repo');
  4352. * const result = await signInWithPopup(auth, provider);
  4353. *
  4354. * // The signed-in user info.
  4355. * const user = result.user;
  4356. * // This gives you a Github Access Token.
  4357. * const credential = GithubAuthProvider.credentialFromResult(result);
  4358. * const token = credential.accessToken;
  4359. * ```
  4360. * @public
  4361. */
  4362. class GithubAuthProvider extends BaseOAuthProvider {
  4363. constructor() {
  4364. super("github.com" /* ProviderId.GITHUB */);
  4365. }
  4366. /**
  4367. * Creates a credential for Github.
  4368. *
  4369. * @param accessToken - Github access token.
  4370. */
  4371. static credential(accessToken) {
  4372. return OAuthCredential._fromParams({
  4373. providerId: GithubAuthProvider.PROVIDER_ID,
  4374. signInMethod: GithubAuthProvider.GITHUB_SIGN_IN_METHOD,
  4375. accessToken
  4376. });
  4377. }
  4378. /**
  4379. * Used to extract the underlying {@link OAuthCredential} from a {@link UserCredential}.
  4380. *
  4381. * @param userCredential - The user credential.
  4382. */
  4383. static credentialFromResult(userCredential) {
  4384. return GithubAuthProvider.credentialFromTaggedObject(userCredential);
  4385. }
  4386. /**
  4387. * Used to extract the underlying {@link OAuthCredential} from a {@link AuthError} which was
  4388. * thrown during a sign-in, link, or reauthenticate operation.
  4389. *
  4390. * @param userCredential - The user credential.
  4391. */
  4392. static credentialFromError(error) {
  4393. return GithubAuthProvider.credentialFromTaggedObject((error.customData || {}));
  4394. }
  4395. static credentialFromTaggedObject({ _tokenResponse: tokenResponse }) {
  4396. if (!tokenResponse || !('oauthAccessToken' in tokenResponse)) {
  4397. return null;
  4398. }
  4399. if (!tokenResponse.oauthAccessToken) {
  4400. return null;
  4401. }
  4402. try {
  4403. return GithubAuthProvider.credential(tokenResponse.oauthAccessToken);
  4404. }
  4405. catch (_a) {
  4406. return null;
  4407. }
  4408. }
  4409. }
  4410. /** Always set to {@link SignInMethod}.GITHUB. */
  4411. GithubAuthProvider.GITHUB_SIGN_IN_METHOD = "github.com" /* SignInMethod.GITHUB */;
  4412. /** Always set to {@link ProviderId}.GITHUB. */
  4413. GithubAuthProvider.PROVIDER_ID = "github.com" /* ProviderId.GITHUB */;
  4414. /**
  4415. * @license
  4416. * Copyright 2020 Google LLC
  4417. *
  4418. * Licensed under the Apache License, Version 2.0 (the "License");
  4419. * you may not use this file except in compliance with the License.
  4420. * You may obtain a copy of the License at
  4421. *
  4422. * http://www.apache.org/licenses/LICENSE-2.0
  4423. *
  4424. * Unless required by applicable law or agreed to in writing, software
  4425. * distributed under the License is distributed on an "AS IS" BASIS,
  4426. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4427. * See the License for the specific language governing permissions and
  4428. * limitations under the License.
  4429. */
  4430. const IDP_REQUEST_URI = 'http://localhost';
  4431. /**
  4432. * @public
  4433. */
  4434. class SAMLAuthCredential extends AuthCredential {
  4435. /** @internal */
  4436. constructor(providerId, pendingToken) {
  4437. super(providerId, providerId);
  4438. this.pendingToken = pendingToken;
  4439. }
  4440. /** @internal */
  4441. _getIdTokenResponse(auth) {
  4442. const request = this.buildRequest();
  4443. return signInWithIdp(auth, request);
  4444. }
  4445. /** @internal */
  4446. _linkToIdToken(auth, idToken) {
  4447. const request = this.buildRequest();
  4448. request.idToken = idToken;
  4449. return signInWithIdp(auth, request);
  4450. }
  4451. /** @internal */
  4452. _getReauthenticationResolver(auth) {
  4453. const request = this.buildRequest();
  4454. request.autoCreate = false;
  4455. return signInWithIdp(auth, request);
  4456. }
  4457. /** {@inheritdoc AuthCredential.toJSON} */
  4458. toJSON() {
  4459. return {
  4460. signInMethod: this.signInMethod,
  4461. providerId: this.providerId,
  4462. pendingToken: this.pendingToken
  4463. };
  4464. }
  4465. /**
  4466. * Static method to deserialize a JSON representation of an object into an
  4467. * {@link AuthCredential}.
  4468. *
  4469. * @param json - Input can be either Object or the stringified representation of the object.
  4470. * When string is provided, JSON.parse would be called first.
  4471. *
  4472. * @returns If the JSON input does not represent an {@link AuthCredential}, null is returned.
  4473. */
  4474. static fromJSON(json) {
  4475. const obj = typeof json === 'string' ? JSON.parse(json) : json;
  4476. const { providerId, signInMethod, pendingToken } = obj;
  4477. if (!providerId ||
  4478. !signInMethod ||
  4479. !pendingToken ||
  4480. providerId !== signInMethod) {
  4481. return null;
  4482. }
  4483. return new SAMLAuthCredential(providerId, pendingToken);
  4484. }
  4485. /**
  4486. * Helper static method to avoid exposing the constructor to end users.
  4487. *
  4488. * @internal
  4489. */
  4490. static _create(providerId, pendingToken) {
  4491. return new SAMLAuthCredential(providerId, pendingToken);
  4492. }
  4493. buildRequest() {
  4494. return {
  4495. requestUri: IDP_REQUEST_URI,
  4496. returnSecureToken: true,
  4497. pendingToken: this.pendingToken
  4498. };
  4499. }
  4500. }
  4501. /**
  4502. * @license
  4503. * Copyright 2020 Google LLC
  4504. *
  4505. * Licensed under the Apache License, Version 2.0 (the "License");
  4506. * you may not use this file except in compliance with the License.
  4507. * You may obtain a copy of the License at
  4508. *
  4509. * http://www.apache.org/licenses/LICENSE-2.0
  4510. *
  4511. * Unless required by applicable law or agreed to in writing, software
  4512. * distributed under the License is distributed on an "AS IS" BASIS,
  4513. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4514. * See the License for the specific language governing permissions and
  4515. * limitations under the License.
  4516. */
  4517. const SAML_PROVIDER_PREFIX = 'saml.';
  4518. /**
  4519. * An {@link AuthProvider} for SAML.
  4520. *
  4521. * @public
  4522. */
  4523. class SAMLAuthProvider extends FederatedAuthProvider {
  4524. /**
  4525. * Constructor. The providerId must start with "saml."
  4526. * @param providerId - SAML provider ID.
  4527. */
  4528. constructor(providerId) {
  4529. _assert(providerId.startsWith(SAML_PROVIDER_PREFIX), "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  4530. super(providerId);
  4531. }
  4532. /**
  4533. * Generates an {@link AuthCredential} from a {@link UserCredential} after a
  4534. * successful SAML flow completes.
  4535. *
  4536. * @remarks
  4537. *
  4538. * For example, to get an {@link AuthCredential}, you could write the
  4539. * following code:
  4540. *
  4541. * ```js
  4542. * const userCredential = await signInWithPopup(auth, samlProvider);
  4543. * const credential = SAMLAuthProvider.credentialFromResult(userCredential);
  4544. * ```
  4545. *
  4546. * @param userCredential - The user credential.
  4547. */
  4548. static credentialFromResult(userCredential) {
  4549. return SAMLAuthProvider.samlCredentialFromTaggedObject(userCredential);
  4550. }
  4551. /**
  4552. * Used to extract the underlying {@link OAuthCredential} from a {@link AuthError} which was
  4553. * thrown during a sign-in, link, or reauthenticate operation.
  4554. *
  4555. * @param userCredential - The user credential.
  4556. */
  4557. static credentialFromError(error) {
  4558. return SAMLAuthProvider.samlCredentialFromTaggedObject((error.customData || {}));
  4559. }
  4560. /**
  4561. * Creates an {@link AuthCredential} from a JSON string or a plain object.
  4562. * @param json - A plain object or a JSON string
  4563. */
  4564. static credentialFromJSON(json) {
  4565. const credential = SAMLAuthCredential.fromJSON(json);
  4566. _assert(credential, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  4567. return credential;
  4568. }
  4569. static samlCredentialFromTaggedObject({ _tokenResponse: tokenResponse }) {
  4570. if (!tokenResponse) {
  4571. return null;
  4572. }
  4573. const { pendingToken, providerId } = tokenResponse;
  4574. if (!pendingToken || !providerId) {
  4575. return null;
  4576. }
  4577. try {
  4578. return SAMLAuthCredential._create(providerId, pendingToken);
  4579. }
  4580. catch (e) {
  4581. return null;
  4582. }
  4583. }
  4584. }
  4585. /**
  4586. * @license
  4587. * Copyright 2020 Google LLC
  4588. *
  4589. * Licensed under the Apache License, Version 2.0 (the "License");
  4590. * you may not use this file except in compliance with the License.
  4591. * You may obtain a copy of the License at
  4592. *
  4593. * http://www.apache.org/licenses/LICENSE-2.0
  4594. *
  4595. * Unless required by applicable law or agreed to in writing, software
  4596. * distributed under the License is distributed on an "AS IS" BASIS,
  4597. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4598. * See the License for the specific language governing permissions and
  4599. * limitations under the License.
  4600. */
  4601. /**
  4602. * Provider for generating an {@link OAuthCredential} for {@link ProviderId}.TWITTER.
  4603. *
  4604. * @example
  4605. * ```javascript
  4606. * // Sign in using a redirect.
  4607. * const provider = new TwitterAuthProvider();
  4608. * // Start a sign in process for an unauthenticated user.
  4609. * await signInWithRedirect(auth, provider);
  4610. * // This will trigger a full page redirect away from your app
  4611. *
  4612. * // After returning from the redirect when your app initializes you can obtain the result
  4613. * const result = await getRedirectResult(auth);
  4614. * if (result) {
  4615. * // This is the signed-in user
  4616. * const user = result.user;
  4617. * // This gives you a Twitter Access Token and Secret.
  4618. * const credential = TwitterAuthProvider.credentialFromResult(result);
  4619. * const token = credential.accessToken;
  4620. * const secret = credential.secret;
  4621. * }
  4622. * ```
  4623. *
  4624. * @example
  4625. * ```javascript
  4626. * // Sign in using a popup.
  4627. * const provider = new TwitterAuthProvider();
  4628. * const result = await signInWithPopup(auth, provider);
  4629. *
  4630. * // The signed-in user info.
  4631. * const user = result.user;
  4632. * // This gives you a Twitter Access Token and Secret.
  4633. * const credential = TwitterAuthProvider.credentialFromResult(result);
  4634. * const token = credential.accessToken;
  4635. * const secret = credential.secret;
  4636. * ```
  4637. *
  4638. * @public
  4639. */
  4640. class TwitterAuthProvider extends BaseOAuthProvider {
  4641. constructor() {
  4642. super("twitter.com" /* ProviderId.TWITTER */);
  4643. }
  4644. /**
  4645. * Creates a credential for Twitter.
  4646. *
  4647. * @param token - Twitter access token.
  4648. * @param secret - Twitter secret.
  4649. */
  4650. static credential(token, secret) {
  4651. return OAuthCredential._fromParams({
  4652. providerId: TwitterAuthProvider.PROVIDER_ID,
  4653. signInMethod: TwitterAuthProvider.TWITTER_SIGN_IN_METHOD,
  4654. oauthToken: token,
  4655. oauthTokenSecret: secret
  4656. });
  4657. }
  4658. /**
  4659. * Used to extract the underlying {@link OAuthCredential} from a {@link UserCredential}.
  4660. *
  4661. * @param userCredential - The user credential.
  4662. */
  4663. static credentialFromResult(userCredential) {
  4664. return TwitterAuthProvider.credentialFromTaggedObject(userCredential);
  4665. }
  4666. /**
  4667. * Used to extract the underlying {@link OAuthCredential} from a {@link AuthError} which was
  4668. * thrown during a sign-in, link, or reauthenticate operation.
  4669. *
  4670. * @param userCredential - The user credential.
  4671. */
  4672. static credentialFromError(error) {
  4673. return TwitterAuthProvider.credentialFromTaggedObject((error.customData || {}));
  4674. }
  4675. static credentialFromTaggedObject({ _tokenResponse: tokenResponse }) {
  4676. if (!tokenResponse) {
  4677. return null;
  4678. }
  4679. const { oauthAccessToken, oauthTokenSecret } = tokenResponse;
  4680. if (!oauthAccessToken || !oauthTokenSecret) {
  4681. return null;
  4682. }
  4683. try {
  4684. return TwitterAuthProvider.credential(oauthAccessToken, oauthTokenSecret);
  4685. }
  4686. catch (_a) {
  4687. return null;
  4688. }
  4689. }
  4690. }
  4691. /** Always set to {@link SignInMethod}.TWITTER. */
  4692. TwitterAuthProvider.TWITTER_SIGN_IN_METHOD = "twitter.com" /* SignInMethod.TWITTER */;
  4693. /** Always set to {@link ProviderId}.TWITTER. */
  4694. TwitterAuthProvider.PROVIDER_ID = "twitter.com" /* ProviderId.TWITTER */;
  4695. /**
  4696. * @license
  4697. * Copyright 2020 Google LLC
  4698. *
  4699. * Licensed under the Apache License, Version 2.0 (the "License");
  4700. * you may not use this file except in compliance with the License.
  4701. * You may obtain a copy of the License at
  4702. *
  4703. * http://www.apache.org/licenses/LICENSE-2.0
  4704. *
  4705. * Unless required by applicable law or agreed to in writing, software
  4706. * distributed under the License is distributed on an "AS IS" BASIS,
  4707. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4708. * See the License for the specific language governing permissions and
  4709. * limitations under the License.
  4710. */
  4711. async function signUp(auth, request) {
  4712. return _performSignInRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:signUp" /* Endpoint.SIGN_UP */, _addTidIfNecessary(auth, request));
  4713. }
  4714. /**
  4715. * @license
  4716. * Copyright 2020 Google LLC
  4717. *
  4718. * Licensed under the Apache License, Version 2.0 (the "License");
  4719. * you may not use this file except in compliance with the License.
  4720. * You may obtain a copy of the License at
  4721. *
  4722. * http://www.apache.org/licenses/LICENSE-2.0
  4723. *
  4724. * Unless required by applicable law or agreed to in writing, software
  4725. * distributed under the License is distributed on an "AS IS" BASIS,
  4726. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4727. * See the License for the specific language governing permissions and
  4728. * limitations under the License.
  4729. */
  4730. class UserCredentialImpl {
  4731. constructor(params) {
  4732. this.user = params.user;
  4733. this.providerId = params.providerId;
  4734. this._tokenResponse = params._tokenResponse;
  4735. this.operationType = params.operationType;
  4736. }
  4737. static async _fromIdTokenResponse(auth, operationType, idTokenResponse, isAnonymous = false) {
  4738. const user = await UserImpl._fromIdTokenResponse(auth, idTokenResponse, isAnonymous);
  4739. const providerId = providerIdForResponse(idTokenResponse);
  4740. const userCred = new UserCredentialImpl({
  4741. user,
  4742. providerId,
  4743. _tokenResponse: idTokenResponse,
  4744. operationType
  4745. });
  4746. return userCred;
  4747. }
  4748. static async _forOperation(user, operationType, response) {
  4749. await user._updateTokensIfNecessary(response, /* reload */ true);
  4750. const providerId = providerIdForResponse(response);
  4751. return new UserCredentialImpl({
  4752. user,
  4753. providerId,
  4754. _tokenResponse: response,
  4755. operationType
  4756. });
  4757. }
  4758. }
  4759. function providerIdForResponse(response) {
  4760. if (response.providerId) {
  4761. return response.providerId;
  4762. }
  4763. if ('phoneNumber' in response) {
  4764. return "phone" /* ProviderId.PHONE */;
  4765. }
  4766. return null;
  4767. }
  4768. /**
  4769. * @license
  4770. * Copyright 2020 Google LLC
  4771. *
  4772. * Licensed under the Apache License, Version 2.0 (the "License");
  4773. * you may not use this file except in compliance with the License.
  4774. * You may obtain a copy of the License at
  4775. *
  4776. * http://www.apache.org/licenses/LICENSE-2.0
  4777. *
  4778. * Unless required by applicable law or agreed to in writing, software
  4779. * distributed under the License is distributed on an "AS IS" BASIS,
  4780. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4781. * See the License for the specific language governing permissions and
  4782. * limitations under the License.
  4783. */
  4784. /**
  4785. * Asynchronously signs in as an anonymous user.
  4786. *
  4787. * @remarks
  4788. * If there is already an anonymous user signed in, that user will be returned; otherwise, a
  4789. * new anonymous user identity will be created and returned.
  4790. *
  4791. * @param auth - The {@link Auth} instance.
  4792. *
  4793. * @public
  4794. */
  4795. async function signInAnonymously(auth) {
  4796. var _a;
  4797. const authInternal = _castAuth(auth);
  4798. await authInternal._initializationPromise;
  4799. if ((_a = authInternal.currentUser) === null || _a === void 0 ? void 0 : _a.isAnonymous) {
  4800. // If an anonymous user is already signed in, no need to sign them in again.
  4801. return new UserCredentialImpl({
  4802. user: authInternal.currentUser,
  4803. providerId: null,
  4804. operationType: "signIn" /* OperationType.SIGN_IN */
  4805. });
  4806. }
  4807. const response = await signUp(authInternal, {
  4808. returnSecureToken: true
  4809. });
  4810. const userCredential = await UserCredentialImpl._fromIdTokenResponse(authInternal, "signIn" /* OperationType.SIGN_IN */, response, true);
  4811. await authInternal._updateCurrentUser(userCredential.user);
  4812. return userCredential;
  4813. }
  4814. /**
  4815. * @license
  4816. * Copyright 2020 Google LLC
  4817. *
  4818. * Licensed under the Apache License, Version 2.0 (the "License");
  4819. * you may not use this file except in compliance with the License.
  4820. * You may obtain a copy of the License at
  4821. *
  4822. * http://www.apache.org/licenses/LICENSE-2.0
  4823. *
  4824. * Unless required by applicable law or agreed to in writing, software
  4825. * distributed under the License is distributed on an "AS IS" BASIS,
  4826. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4827. * See the License for the specific language governing permissions and
  4828. * limitations under the License.
  4829. */
  4830. class MultiFactorError extends util.FirebaseError {
  4831. constructor(auth, error, operationType, user) {
  4832. var _a;
  4833. super(error.code, error.message);
  4834. this.operationType = operationType;
  4835. this.user = user;
  4836. // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
  4837. Object.setPrototypeOf(this, MultiFactorError.prototype);
  4838. this.customData = {
  4839. appName: auth.name,
  4840. tenantId: (_a = auth.tenantId) !== null && _a !== void 0 ? _a : undefined,
  4841. _serverResponse: error.customData._serverResponse,
  4842. operationType
  4843. };
  4844. }
  4845. static _fromErrorAndOperation(auth, error, operationType, user) {
  4846. return new MultiFactorError(auth, error, operationType, user);
  4847. }
  4848. }
  4849. function _processCredentialSavingMfaContextIfNecessary(auth, operationType, credential, user) {
  4850. const idTokenProvider = operationType === "reauthenticate" /* OperationType.REAUTHENTICATE */
  4851. ? credential._getReauthenticationResolver(auth)
  4852. : credential._getIdTokenResponse(auth);
  4853. return idTokenProvider.catch(error => {
  4854. if (error.code === `auth/${"multi-factor-auth-required" /* AuthErrorCode.MFA_REQUIRED */}`) {
  4855. throw MultiFactorError._fromErrorAndOperation(auth, error, operationType, user);
  4856. }
  4857. throw error;
  4858. });
  4859. }
  4860. /**
  4861. * @license
  4862. * Copyright 2020 Google LLC
  4863. *
  4864. * Licensed under the Apache License, Version 2.0 (the "License");
  4865. * you may not use this file except in compliance with the License.
  4866. * You may obtain a copy of the License at
  4867. *
  4868. * http://www.apache.org/licenses/LICENSE-2.0
  4869. *
  4870. * Unless required by applicable law or agreed to in writing, software
  4871. * distributed under the License is distributed on an "AS IS" BASIS,
  4872. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4873. * See the License for the specific language governing permissions and
  4874. * limitations under the License.
  4875. */
  4876. /**
  4877. * Takes a set of UserInfo provider data and converts it to a set of names
  4878. */
  4879. function providerDataAsNames(providerData) {
  4880. return new Set(providerData
  4881. .map(({ providerId }) => providerId)
  4882. .filter(pid => !!pid));
  4883. }
  4884. /**
  4885. * @license
  4886. * Copyright 2019 Google LLC
  4887. *
  4888. * Licensed under the Apache License, Version 2.0 (the "License");
  4889. * you may not use this file except in compliance with the License.
  4890. * You may obtain a copy of the License at
  4891. *
  4892. * http://www.apache.org/licenses/LICENSE-2.0
  4893. *
  4894. * Unless required by applicable law or agreed to in writing, software
  4895. * distributed under the License is distributed on an "AS IS" BASIS,
  4896. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4897. * See the License for the specific language governing permissions and
  4898. * limitations under the License.
  4899. */
  4900. /**
  4901. * Unlinks a provider from a user account.
  4902. *
  4903. * @param user - The user.
  4904. * @param providerId - The provider to unlink.
  4905. *
  4906. * @public
  4907. */
  4908. async function unlink(user, providerId) {
  4909. const userInternal = util.getModularInstance(user);
  4910. await _assertLinkedStatus(true, userInternal, providerId);
  4911. const { providerUserInfo } = await deleteLinkedAccounts(userInternal.auth, {
  4912. idToken: await userInternal.getIdToken(),
  4913. deleteProvider: [providerId]
  4914. });
  4915. const providersLeft = providerDataAsNames(providerUserInfo || []);
  4916. userInternal.providerData = userInternal.providerData.filter(pd => providersLeft.has(pd.providerId));
  4917. if (!providersLeft.has("phone" /* ProviderId.PHONE */)) {
  4918. userInternal.phoneNumber = null;
  4919. }
  4920. await userInternal.auth._persistUserIfCurrent(userInternal);
  4921. return userInternal;
  4922. }
  4923. async function _link$1(user, credential, bypassAuthState = false) {
  4924. const response = await _logoutIfInvalidated(user, credential._linkToIdToken(user.auth, await user.getIdToken()), bypassAuthState);
  4925. return UserCredentialImpl._forOperation(user, "link" /* OperationType.LINK */, response);
  4926. }
  4927. async function _assertLinkedStatus(expected, user, provider) {
  4928. await _reloadWithoutSaving(user);
  4929. const providerIds = providerDataAsNames(user.providerData);
  4930. const code = expected === false
  4931. ? "provider-already-linked" /* AuthErrorCode.PROVIDER_ALREADY_LINKED */
  4932. : "no-such-provider" /* AuthErrorCode.NO_SUCH_PROVIDER */;
  4933. _assert(providerIds.has(provider) === expected, user.auth, code);
  4934. }
  4935. /**
  4936. * @license
  4937. * Copyright 2019 Google LLC
  4938. *
  4939. * Licensed under the Apache License, Version 2.0 (the "License");
  4940. * you may not use this file except in compliance with the License.
  4941. * You may obtain a copy of the License at
  4942. *
  4943. * http://www.apache.org/licenses/LICENSE-2.0
  4944. *
  4945. * Unless required by applicable law or agreed to in writing, software
  4946. * distributed under the License is distributed on an "AS IS" BASIS,
  4947. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4948. * See the License for the specific language governing permissions and
  4949. * limitations under the License.
  4950. */
  4951. async function _reauthenticate(user, credential, bypassAuthState = false) {
  4952. const { auth } = user;
  4953. const operationType = "reauthenticate" /* OperationType.REAUTHENTICATE */;
  4954. try {
  4955. const response = await _logoutIfInvalidated(user, _processCredentialSavingMfaContextIfNecessary(auth, operationType, credential, user), bypassAuthState);
  4956. _assert(response.idToken, auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  4957. const parsed = _parseToken(response.idToken);
  4958. _assert(parsed, auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  4959. const { sub: localId } = parsed;
  4960. _assert(user.uid === localId, auth, "user-mismatch" /* AuthErrorCode.USER_MISMATCH */);
  4961. return UserCredentialImpl._forOperation(user, operationType, response);
  4962. }
  4963. catch (e) {
  4964. // Convert user deleted error into user mismatch
  4965. if ((e === null || e === void 0 ? void 0 : e.code) === `auth/${"user-not-found" /* AuthErrorCode.USER_DELETED */}`) {
  4966. _fail(auth, "user-mismatch" /* AuthErrorCode.USER_MISMATCH */);
  4967. }
  4968. throw e;
  4969. }
  4970. }
  4971. /**
  4972. * @license
  4973. * Copyright 2020 Google LLC
  4974. *
  4975. * Licensed under the Apache License, Version 2.0 (the "License");
  4976. * you may not use this file except in compliance with the License.
  4977. * You may obtain a copy of the License at
  4978. *
  4979. * http://www.apache.org/licenses/LICENSE-2.0
  4980. *
  4981. * Unless required by applicable law or agreed to in writing, software
  4982. * distributed under the License is distributed on an "AS IS" BASIS,
  4983. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4984. * See the License for the specific language governing permissions and
  4985. * limitations under the License.
  4986. */
  4987. async function _signInWithCredential(auth, credential, bypassAuthState = false) {
  4988. const operationType = "signIn" /* OperationType.SIGN_IN */;
  4989. const response = await _processCredentialSavingMfaContextIfNecessary(auth, operationType, credential);
  4990. const userCredential = await UserCredentialImpl._fromIdTokenResponse(auth, operationType, response);
  4991. if (!bypassAuthState) {
  4992. await auth._updateCurrentUser(userCredential.user);
  4993. }
  4994. return userCredential;
  4995. }
  4996. /**
  4997. * Asynchronously signs in with the given credentials.
  4998. *
  4999. * @remarks
  5000. * An {@link AuthProvider} can be used to generate the credential.
  5001. *
  5002. * @param auth - The {@link Auth} instance.
  5003. * @param credential - The auth credential.
  5004. *
  5005. * @public
  5006. */
  5007. async function signInWithCredential(auth, credential) {
  5008. return _signInWithCredential(_castAuth(auth), credential);
  5009. }
  5010. /**
  5011. * Links the user account with the given credentials.
  5012. *
  5013. * @remarks
  5014. * An {@link AuthProvider} can be used to generate the credential.
  5015. *
  5016. * @param user - The user.
  5017. * @param credential - The auth credential.
  5018. *
  5019. * @public
  5020. */
  5021. async function linkWithCredential(user, credential) {
  5022. const userInternal = util.getModularInstance(user);
  5023. await _assertLinkedStatus(false, userInternal, credential.providerId);
  5024. return _link$1(userInternal, credential);
  5025. }
  5026. /**
  5027. * Re-authenticates a user using a fresh credential.
  5028. *
  5029. * @remarks
  5030. * Use before operations such as {@link updatePassword} that require tokens from recent sign-in
  5031. * attempts. This method can be used to recover from a `CREDENTIAL_TOO_OLD_LOGIN_AGAIN` error
  5032. * or a `TOKEN_EXPIRED` error.
  5033. *
  5034. * @param user - The user.
  5035. * @param credential - The auth credential.
  5036. *
  5037. * @public
  5038. */
  5039. async function reauthenticateWithCredential(user, credential) {
  5040. return _reauthenticate(util.getModularInstance(user), credential);
  5041. }
  5042. /**
  5043. * @license
  5044. * Copyright 2020 Google LLC
  5045. *
  5046. * Licensed under the Apache License, Version 2.0 (the "License");
  5047. * you may not use this file except in compliance with the License.
  5048. * You may obtain a copy of the License at
  5049. *
  5050. * http://www.apache.org/licenses/LICENSE-2.0
  5051. *
  5052. * Unless required by applicable law or agreed to in writing, software
  5053. * distributed under the License is distributed on an "AS IS" BASIS,
  5054. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5055. * See the License for the specific language governing permissions and
  5056. * limitations under the License.
  5057. */
  5058. async function signInWithCustomToken$1(auth, request) {
  5059. return _performSignInRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:signInWithCustomToken" /* Endpoint.SIGN_IN_WITH_CUSTOM_TOKEN */, _addTidIfNecessary(auth, request));
  5060. }
  5061. /**
  5062. * @license
  5063. * Copyright 2020 Google LLC
  5064. *
  5065. * Licensed under the Apache License, Version 2.0 (the "License");
  5066. * you may not use this file except in compliance with the License.
  5067. * You may obtain a copy of the License at
  5068. *
  5069. * http://www.apache.org/licenses/LICENSE-2.0
  5070. *
  5071. * Unless required by applicable law or agreed to in writing, software
  5072. * distributed under the License is distributed on an "AS IS" BASIS,
  5073. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5074. * See the License for the specific language governing permissions and
  5075. * limitations under the License.
  5076. */
  5077. /**
  5078. * Asynchronously signs in using a custom token.
  5079. *
  5080. * @remarks
  5081. * Custom tokens are used to integrate Firebase Auth with existing auth systems, and must
  5082. * be generated by an auth backend using the
  5083. * {@link https://firebase.google.com/docs/reference/admin/node/admin.auth.Auth#createcustomtoken | createCustomToken}
  5084. * method in the {@link https://firebase.google.com/docs/auth/admin | Admin SDK} .
  5085. *
  5086. * Fails with an error if the token is invalid, expired, or not accepted by the Firebase Auth service.
  5087. *
  5088. * @param auth - The {@link Auth} instance.
  5089. * @param customToken - The custom token to sign in with.
  5090. *
  5091. * @public
  5092. */
  5093. async function signInWithCustomToken(auth, customToken) {
  5094. const authInternal = _castAuth(auth);
  5095. const response = await signInWithCustomToken$1(authInternal, {
  5096. token: customToken,
  5097. returnSecureToken: true
  5098. });
  5099. const cred = await UserCredentialImpl._fromIdTokenResponse(authInternal, "signIn" /* OperationType.SIGN_IN */, response);
  5100. await authInternal._updateCurrentUser(cred.user);
  5101. return cred;
  5102. }
  5103. /**
  5104. * @license
  5105. * Copyright 2020 Google LLC
  5106. *
  5107. * Licensed under the Apache License, Version 2.0 (the "License");
  5108. * you may not use this file except in compliance with the License.
  5109. * You may obtain a copy of the License at
  5110. *
  5111. * http://www.apache.org/licenses/LICENSE-2.0
  5112. *
  5113. * Unless required by applicable law or agreed to in writing, software
  5114. * distributed under the License is distributed on an "AS IS" BASIS,
  5115. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5116. * See the License for the specific language governing permissions and
  5117. * limitations under the License.
  5118. */
  5119. class MultiFactorInfoImpl {
  5120. constructor(factorId, response) {
  5121. this.factorId = factorId;
  5122. this.uid = response.mfaEnrollmentId;
  5123. this.enrollmentTime = new Date(response.enrolledAt).toUTCString();
  5124. this.displayName = response.displayName;
  5125. }
  5126. static _fromServerResponse(auth, enrollment) {
  5127. if ('phoneInfo' in enrollment) {
  5128. return PhoneMultiFactorInfoImpl._fromServerResponse(auth, enrollment);
  5129. }
  5130. else if ('totpInfo' in enrollment) {
  5131. return TotpMultiFactorInfoImpl._fromServerResponse(auth, enrollment);
  5132. }
  5133. return _fail(auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  5134. }
  5135. }
  5136. class PhoneMultiFactorInfoImpl extends MultiFactorInfoImpl {
  5137. constructor(response) {
  5138. super("phone" /* FactorId.PHONE */, response);
  5139. this.phoneNumber = response.phoneInfo;
  5140. }
  5141. static _fromServerResponse(_auth, enrollment) {
  5142. return new PhoneMultiFactorInfoImpl(enrollment);
  5143. }
  5144. }
  5145. class TotpMultiFactorInfoImpl extends MultiFactorInfoImpl {
  5146. constructor(response) {
  5147. super("totp" /* FactorId.TOTP */, response);
  5148. }
  5149. static _fromServerResponse(_auth, enrollment) {
  5150. return new TotpMultiFactorInfoImpl(enrollment);
  5151. }
  5152. }
  5153. /**
  5154. * @license
  5155. * Copyright 2020 Google LLC
  5156. *
  5157. * Licensed under the Apache License, Version 2.0 (the "License");
  5158. * you may not use this file except in compliance with the License.
  5159. * You may obtain a copy of the License at
  5160. *
  5161. * http://www.apache.org/licenses/LICENSE-2.0
  5162. *
  5163. * Unless required by applicable law or agreed to in writing, software
  5164. * distributed under the License is distributed on an "AS IS" BASIS,
  5165. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5166. * See the License for the specific language governing permissions and
  5167. * limitations under the License.
  5168. */
  5169. function _setActionCodeSettingsOnRequest(auth, request, actionCodeSettings) {
  5170. var _a;
  5171. _assert(((_a = actionCodeSettings.url) === null || _a === void 0 ? void 0 : _a.length) > 0, auth, "invalid-continue-uri" /* AuthErrorCode.INVALID_CONTINUE_URI */);
  5172. _assert(typeof actionCodeSettings.dynamicLinkDomain === 'undefined' ||
  5173. actionCodeSettings.dynamicLinkDomain.length > 0, auth, "invalid-dynamic-link-domain" /* AuthErrorCode.INVALID_DYNAMIC_LINK_DOMAIN */);
  5174. request.continueUrl = actionCodeSettings.url;
  5175. request.dynamicLinkDomain = actionCodeSettings.dynamicLinkDomain;
  5176. request.canHandleCodeInApp = actionCodeSettings.handleCodeInApp;
  5177. if (actionCodeSettings.iOS) {
  5178. _assert(actionCodeSettings.iOS.bundleId.length > 0, auth, "missing-ios-bundle-id" /* AuthErrorCode.MISSING_IOS_BUNDLE_ID */);
  5179. request.iOSBundleId = actionCodeSettings.iOS.bundleId;
  5180. }
  5181. if (actionCodeSettings.android) {
  5182. _assert(actionCodeSettings.android.packageName.length > 0, auth, "missing-android-pkg-name" /* AuthErrorCode.MISSING_ANDROID_PACKAGE_NAME */);
  5183. request.androidInstallApp = actionCodeSettings.android.installApp;
  5184. request.androidMinimumVersionCode =
  5185. actionCodeSettings.android.minimumVersion;
  5186. request.androidPackageName = actionCodeSettings.android.packageName;
  5187. }
  5188. }
  5189. /**
  5190. * @license
  5191. * Copyright 2020 Google LLC
  5192. *
  5193. * Licensed under the Apache License, Version 2.0 (the "License");
  5194. * you may not use this file except in compliance with the License.
  5195. * You may obtain a copy of the License at
  5196. *
  5197. * http://www.apache.org/licenses/LICENSE-2.0
  5198. *
  5199. * Unless required by applicable law or agreed to in writing, software
  5200. * distributed under the License is distributed on an "AS IS" BASIS,
  5201. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5202. * See the License for the specific language governing permissions and
  5203. * limitations under the License.
  5204. */
  5205. /**
  5206. * Sends a password reset email to the given email address.
  5207. *
  5208. * @remarks
  5209. * To complete the password reset, call {@link confirmPasswordReset} with the code supplied in
  5210. * the email sent to the user, along with the new password specified by the user.
  5211. *
  5212. * @example
  5213. * ```javascript
  5214. * const actionCodeSettings = {
  5215. * url: 'https://www.example.com/?email=user@example.com',
  5216. * iOS: {
  5217. * bundleId: 'com.example.ios'
  5218. * },
  5219. * android: {
  5220. * packageName: 'com.example.android',
  5221. * installApp: true,
  5222. * minimumVersion: '12'
  5223. * },
  5224. * handleCodeInApp: true
  5225. * };
  5226. * await sendPasswordResetEmail(auth, 'user@example.com', actionCodeSettings);
  5227. * // Obtain code from user.
  5228. * await confirmPasswordReset('user@example.com', code);
  5229. * ```
  5230. *
  5231. * @param auth - The {@link Auth} instance.
  5232. * @param email - The user's email address.
  5233. * @param actionCodeSettings - The {@link ActionCodeSettings}.
  5234. *
  5235. * @public
  5236. */
  5237. async function sendPasswordResetEmail(auth, email, actionCodeSettings) {
  5238. var _a;
  5239. const authInternal = _castAuth(auth);
  5240. const request = {
  5241. requestType: "PASSWORD_RESET" /* ActionCodeOperation.PASSWORD_RESET */,
  5242. email,
  5243. clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */
  5244. };
  5245. if ((_a = authInternal._getRecaptchaConfig()) === null || _a === void 0 ? void 0 : _a.emailPasswordEnabled) {
  5246. const requestWithRecaptcha = await injectRecaptchaFields(authInternal, request, "getOobCode" /* RecaptchaActionName.GET_OOB_CODE */, true);
  5247. if (actionCodeSettings) {
  5248. _setActionCodeSettingsOnRequest(authInternal, requestWithRecaptcha, actionCodeSettings);
  5249. }
  5250. await sendPasswordResetEmail$1(authInternal, requestWithRecaptcha);
  5251. }
  5252. else {
  5253. if (actionCodeSettings) {
  5254. _setActionCodeSettingsOnRequest(authInternal, request, actionCodeSettings);
  5255. }
  5256. await sendPasswordResetEmail$1(authInternal, request)
  5257. .catch(async (error) => {
  5258. if (error.code === `auth/${"missing-recaptcha-token" /* AuthErrorCode.MISSING_RECAPTCHA_TOKEN */}`) {
  5259. console.log('Password resets are protected by reCAPTCHA for this project. Automatically triggering the reCAPTCHA flow and restarting the password reset flow.');
  5260. const requestWithRecaptcha = await injectRecaptchaFields(authInternal, request, "getOobCode" /* RecaptchaActionName.GET_OOB_CODE */, true);
  5261. if (actionCodeSettings) {
  5262. _setActionCodeSettingsOnRequest(authInternal, requestWithRecaptcha, actionCodeSettings);
  5263. }
  5264. await sendPasswordResetEmail$1(authInternal, requestWithRecaptcha);
  5265. }
  5266. else {
  5267. return Promise.reject(error);
  5268. }
  5269. });
  5270. }
  5271. }
  5272. /**
  5273. * Completes the password reset process, given a confirmation code and new password.
  5274. *
  5275. * @param auth - The {@link Auth} instance.
  5276. * @param oobCode - A confirmation code sent to the user.
  5277. * @param newPassword - The new password.
  5278. *
  5279. * @public
  5280. */
  5281. async function confirmPasswordReset(auth, oobCode, newPassword) {
  5282. await resetPassword(util.getModularInstance(auth), {
  5283. oobCode,
  5284. newPassword
  5285. });
  5286. // Do not return the email.
  5287. }
  5288. /**
  5289. * Applies a verification code sent to the user by email or other out-of-band mechanism.
  5290. *
  5291. * @param auth - The {@link Auth} instance.
  5292. * @param oobCode - A verification code sent to the user.
  5293. *
  5294. * @public
  5295. */
  5296. async function applyActionCode(auth, oobCode) {
  5297. await applyActionCode$1(util.getModularInstance(auth), { oobCode });
  5298. }
  5299. /**
  5300. * Checks a verification code sent to the user by email or other out-of-band mechanism.
  5301. *
  5302. * @returns metadata about the code.
  5303. *
  5304. * @param auth - The {@link Auth} instance.
  5305. * @param oobCode - A verification code sent to the user.
  5306. *
  5307. * @public
  5308. */
  5309. async function checkActionCode(auth, oobCode) {
  5310. const authModular = util.getModularInstance(auth);
  5311. const response = await resetPassword(authModular, { oobCode });
  5312. // Email could be empty only if the request type is EMAIL_SIGNIN or
  5313. // VERIFY_AND_CHANGE_EMAIL.
  5314. // New email should not be empty if the request type is
  5315. // VERIFY_AND_CHANGE_EMAIL.
  5316. // Multi-factor info could not be empty if the request type is
  5317. // REVERT_SECOND_FACTOR_ADDITION.
  5318. const operation = response.requestType;
  5319. _assert(operation, authModular, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  5320. switch (operation) {
  5321. case "EMAIL_SIGNIN" /* ActionCodeOperation.EMAIL_SIGNIN */:
  5322. break;
  5323. case "VERIFY_AND_CHANGE_EMAIL" /* ActionCodeOperation.VERIFY_AND_CHANGE_EMAIL */:
  5324. _assert(response.newEmail, authModular, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  5325. break;
  5326. case "REVERT_SECOND_FACTOR_ADDITION" /* ActionCodeOperation.REVERT_SECOND_FACTOR_ADDITION */:
  5327. _assert(response.mfaInfo, authModular, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  5328. // fall through
  5329. default:
  5330. _assert(response.email, authModular, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  5331. }
  5332. // The multi-factor info for revert second factor addition
  5333. let multiFactorInfo = null;
  5334. if (response.mfaInfo) {
  5335. multiFactorInfo = MultiFactorInfoImpl._fromServerResponse(_castAuth(authModular), response.mfaInfo);
  5336. }
  5337. return {
  5338. data: {
  5339. email: (response.requestType === "VERIFY_AND_CHANGE_EMAIL" /* ActionCodeOperation.VERIFY_AND_CHANGE_EMAIL */
  5340. ? response.newEmail
  5341. : response.email) || null,
  5342. previousEmail: (response.requestType === "VERIFY_AND_CHANGE_EMAIL" /* ActionCodeOperation.VERIFY_AND_CHANGE_EMAIL */
  5343. ? response.email
  5344. : response.newEmail) || null,
  5345. multiFactorInfo
  5346. },
  5347. operation
  5348. };
  5349. }
  5350. /**
  5351. * Checks a password reset code sent to the user by email or other out-of-band mechanism.
  5352. *
  5353. * @returns the user's email address if valid.
  5354. *
  5355. * @param auth - The {@link Auth} instance.
  5356. * @param code - A verification code sent to the user.
  5357. *
  5358. * @public
  5359. */
  5360. async function verifyPasswordResetCode(auth, code) {
  5361. const { data } = await checkActionCode(util.getModularInstance(auth), code);
  5362. // Email should always be present since a code was sent to it
  5363. return data.email;
  5364. }
  5365. /**
  5366. * Creates a new user account associated with the specified email address and password.
  5367. *
  5368. * @remarks
  5369. * On successful creation of the user account, this user will also be signed in to your application.
  5370. *
  5371. * User account creation can fail if the account already exists or the password is invalid.
  5372. *
  5373. * Note: The email address acts as a unique identifier for the user and enables an email-based
  5374. * password reset. This function will create a new user account and set the initial user password.
  5375. *
  5376. * @param auth - The {@link Auth} instance.
  5377. * @param email - The user's email address.
  5378. * @param password - The user's chosen password.
  5379. *
  5380. * @public
  5381. */
  5382. async function createUserWithEmailAndPassword(auth, email, password) {
  5383. var _a;
  5384. const authInternal = _castAuth(auth);
  5385. const request = {
  5386. returnSecureToken: true,
  5387. email,
  5388. password,
  5389. clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */
  5390. };
  5391. let signUpResponse;
  5392. if ((_a = authInternal._getRecaptchaConfig()) === null || _a === void 0 ? void 0 : _a.emailPasswordEnabled) {
  5393. const requestWithRecaptcha = await injectRecaptchaFields(authInternal, request, "signUpPassword" /* RecaptchaActionName.SIGN_UP_PASSWORD */);
  5394. signUpResponse = signUp(authInternal, requestWithRecaptcha);
  5395. }
  5396. else {
  5397. signUpResponse = signUp(authInternal, request).catch(async (error) => {
  5398. if (error.code === `auth/${"missing-recaptcha-token" /* AuthErrorCode.MISSING_RECAPTCHA_TOKEN */}`) {
  5399. console.log('Sign-up is protected by reCAPTCHA for this project. Automatically triggering the reCAPTCHA flow and restarting the sign-up flow.');
  5400. const requestWithRecaptcha = await injectRecaptchaFields(authInternal, request, "signUpPassword" /* RecaptchaActionName.SIGN_UP_PASSWORD */);
  5401. return signUp(authInternal, requestWithRecaptcha);
  5402. }
  5403. else {
  5404. return Promise.reject(error);
  5405. }
  5406. });
  5407. }
  5408. const response = await signUpResponse.catch(error => {
  5409. return Promise.reject(error);
  5410. });
  5411. const userCredential = await UserCredentialImpl._fromIdTokenResponse(authInternal, "signIn" /* OperationType.SIGN_IN */, response);
  5412. await authInternal._updateCurrentUser(userCredential.user);
  5413. return userCredential;
  5414. }
  5415. /**
  5416. * Asynchronously signs in using an email and password.
  5417. *
  5418. * @remarks
  5419. * Fails with an error if the email address and password do not match.
  5420. *
  5421. * Note: The user's password is NOT the password used to access the user's email account. The
  5422. * email address serves as a unique identifier for the user, and the password is used to access
  5423. * the user's account in your Firebase project. See also: {@link createUserWithEmailAndPassword}.
  5424. *
  5425. * @param auth - The {@link Auth} instance.
  5426. * @param email - The users email address.
  5427. * @param password - The users password.
  5428. *
  5429. * @public
  5430. */
  5431. function signInWithEmailAndPassword(auth, email, password) {
  5432. return signInWithCredential(util.getModularInstance(auth), EmailAuthProvider.credential(email, password));
  5433. }
  5434. /**
  5435. * @license
  5436. * Copyright 2020 Google LLC
  5437. *
  5438. * Licensed under the Apache License, Version 2.0 (the "License");
  5439. * you may not use this file except in compliance with the License.
  5440. * You may obtain a copy of the License at
  5441. *
  5442. * http://www.apache.org/licenses/LICENSE-2.0
  5443. *
  5444. * Unless required by applicable law or agreed to in writing, software
  5445. * distributed under the License is distributed on an "AS IS" BASIS,
  5446. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5447. * See the License for the specific language governing permissions and
  5448. * limitations under the License.
  5449. */
  5450. /**
  5451. * Sends a sign-in email link to the user with the specified email.
  5452. *
  5453. * @remarks
  5454. * The sign-in operation has to always be completed in the app unlike other out of band email
  5455. * actions (password reset and email verifications). This is because, at the end of the flow,
  5456. * the user is expected to be signed in and their Auth state persisted within the app.
  5457. *
  5458. * To complete sign in with the email link, call {@link signInWithEmailLink} with the email
  5459. * address and the email link supplied in the email sent to the user.
  5460. *
  5461. * @example
  5462. * ```javascript
  5463. * const actionCodeSettings = {
  5464. * url: 'https://www.example.com/?email=user@example.com',
  5465. * iOS: {
  5466. * bundleId: 'com.example.ios'
  5467. * },
  5468. * android: {
  5469. * packageName: 'com.example.android',
  5470. * installApp: true,
  5471. * minimumVersion: '12'
  5472. * },
  5473. * handleCodeInApp: true
  5474. * };
  5475. * await sendSignInLinkToEmail(auth, 'user@example.com', actionCodeSettings);
  5476. * // Obtain emailLink from the user.
  5477. * if(isSignInWithEmailLink(auth, emailLink)) {
  5478. * await signInWithEmailLink(auth, 'user@example.com', emailLink);
  5479. * }
  5480. * ```
  5481. *
  5482. * @param authInternal - The {@link Auth} instance.
  5483. * @param email - The user's email address.
  5484. * @param actionCodeSettings - The {@link ActionCodeSettings}.
  5485. *
  5486. * @public
  5487. */
  5488. async function sendSignInLinkToEmail(auth, email, actionCodeSettings) {
  5489. var _a;
  5490. const authInternal = _castAuth(auth);
  5491. const request = {
  5492. requestType: "EMAIL_SIGNIN" /* ActionCodeOperation.EMAIL_SIGNIN */,
  5493. email,
  5494. clientType: "CLIENT_TYPE_WEB" /* RecaptchaClientType.WEB */
  5495. };
  5496. function setActionCodeSettings(request, actionCodeSettings) {
  5497. _assert(actionCodeSettings.handleCodeInApp, authInternal, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  5498. if (actionCodeSettings) {
  5499. _setActionCodeSettingsOnRequest(authInternal, request, actionCodeSettings);
  5500. }
  5501. }
  5502. if ((_a = authInternal._getRecaptchaConfig()) === null || _a === void 0 ? void 0 : _a.emailPasswordEnabled) {
  5503. const requestWithRecaptcha = await injectRecaptchaFields(authInternal, request, "getOobCode" /* RecaptchaActionName.GET_OOB_CODE */, true);
  5504. setActionCodeSettings(requestWithRecaptcha, actionCodeSettings);
  5505. await sendSignInLinkToEmail$1(authInternal, requestWithRecaptcha);
  5506. }
  5507. else {
  5508. setActionCodeSettings(request, actionCodeSettings);
  5509. await sendSignInLinkToEmail$1(authInternal, request)
  5510. .catch(async (error) => {
  5511. if (error.code === `auth/${"missing-recaptcha-token" /* AuthErrorCode.MISSING_RECAPTCHA_TOKEN */}`) {
  5512. console.log('Email link sign-in is protected by reCAPTCHA for this project. Automatically triggering the reCAPTCHA flow and restarting the sign-in flow.');
  5513. const requestWithRecaptcha = await injectRecaptchaFields(authInternal, request, "getOobCode" /* RecaptchaActionName.GET_OOB_CODE */, true);
  5514. setActionCodeSettings(requestWithRecaptcha, actionCodeSettings);
  5515. await sendSignInLinkToEmail$1(authInternal, requestWithRecaptcha);
  5516. }
  5517. else {
  5518. return Promise.reject(error);
  5519. }
  5520. });
  5521. }
  5522. }
  5523. /**
  5524. * Checks if an incoming link is a sign-in with email link suitable for {@link signInWithEmailLink}.
  5525. *
  5526. * @param auth - The {@link Auth} instance.
  5527. * @param emailLink - The link sent to the user's email address.
  5528. *
  5529. * @public
  5530. */
  5531. function isSignInWithEmailLink(auth, emailLink) {
  5532. const actionCodeUrl = ActionCodeURL.parseLink(emailLink);
  5533. return (actionCodeUrl === null || actionCodeUrl === void 0 ? void 0 : actionCodeUrl.operation) === "EMAIL_SIGNIN" /* ActionCodeOperation.EMAIL_SIGNIN */;
  5534. }
  5535. /**
  5536. * Asynchronously signs in using an email and sign-in email link.
  5537. *
  5538. * @remarks
  5539. * If no link is passed, the link is inferred from the current URL.
  5540. *
  5541. * Fails with an error if the email address is invalid or OTP in email link expires.
  5542. *
  5543. * Note: Confirm the link is a sign-in email link before calling this method firebase.auth.Auth.isSignInWithEmailLink.
  5544. *
  5545. * @example
  5546. * ```javascript
  5547. * const actionCodeSettings = {
  5548. * url: 'https://www.example.com/?email=user@example.com',
  5549. * iOS: {
  5550. * bundleId: 'com.example.ios'
  5551. * },
  5552. * android: {
  5553. * packageName: 'com.example.android',
  5554. * installApp: true,
  5555. * minimumVersion: '12'
  5556. * },
  5557. * handleCodeInApp: true
  5558. * };
  5559. * await sendSignInLinkToEmail(auth, 'user@example.com', actionCodeSettings);
  5560. * // Obtain emailLink from the user.
  5561. * if(isSignInWithEmailLink(auth, emailLink)) {
  5562. * await signInWithEmailLink(auth, 'user@example.com', emailLink);
  5563. * }
  5564. * ```
  5565. *
  5566. * @param auth - The {@link Auth} instance.
  5567. * @param email - The user's email address.
  5568. * @param emailLink - The link sent to the user's email address.
  5569. *
  5570. * @public
  5571. */
  5572. async function signInWithEmailLink(auth, email, emailLink) {
  5573. const authModular = util.getModularInstance(auth);
  5574. const credential = EmailAuthProvider.credentialWithLink(email, emailLink || _getCurrentUrl());
  5575. // Check if the tenant ID in the email link matches the tenant ID on Auth
  5576. // instance.
  5577. _assert(credential._tenantId === (authModular.tenantId || null), authModular, "tenant-id-mismatch" /* AuthErrorCode.TENANT_ID_MISMATCH */);
  5578. return signInWithCredential(authModular, credential);
  5579. }
  5580. /**
  5581. * @license
  5582. * Copyright 2020 Google LLC
  5583. *
  5584. * Licensed under the Apache License, Version 2.0 (the "License");
  5585. * you may not use this file except in compliance with the License.
  5586. * You may obtain a copy of the License at
  5587. *
  5588. * http://www.apache.org/licenses/LICENSE-2.0
  5589. *
  5590. * Unless required by applicable law or agreed to in writing, software
  5591. * distributed under the License is distributed on an "AS IS" BASIS,
  5592. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5593. * See the License for the specific language governing permissions and
  5594. * limitations under the License.
  5595. */
  5596. async function createAuthUri(auth, request) {
  5597. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:createAuthUri" /* Endpoint.CREATE_AUTH_URI */, _addTidIfNecessary(auth, request));
  5598. }
  5599. /**
  5600. * @license
  5601. * Copyright 2020 Google LLC
  5602. *
  5603. * Licensed under the Apache License, Version 2.0 (the "License");
  5604. * you may not use this file except in compliance with the License.
  5605. * You may obtain a copy of the License at
  5606. *
  5607. * http://www.apache.org/licenses/LICENSE-2.0
  5608. *
  5609. * Unless required by applicable law or agreed to in writing, software
  5610. * distributed under the License is distributed on an "AS IS" BASIS,
  5611. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5612. * See the License for the specific language governing permissions and
  5613. * limitations under the License.
  5614. */
  5615. /**
  5616. * Gets the list of possible sign in methods for the given email address.
  5617. *
  5618. * @remarks
  5619. * This is useful to differentiate methods of sign-in for the same provider, eg.
  5620. * {@link EmailAuthProvider} which has 2 methods of sign-in,
  5621. * {@link SignInMethod}.EMAIL_PASSWORD and
  5622. * {@link SignInMethod}.EMAIL_LINK.
  5623. *
  5624. * @param auth - The {@link Auth} instance.
  5625. * @param email - The user's email address.
  5626. *
  5627. * @public
  5628. */
  5629. async function fetchSignInMethodsForEmail(auth, email) {
  5630. // createAuthUri returns an error if continue URI is not http or https.
  5631. // For environments like Cordova, Chrome extensions, native frameworks, file
  5632. // systems, etc, use http://localhost as continue URL.
  5633. const continueUri = _isHttpOrHttps() ? _getCurrentUrl() : 'http://localhost';
  5634. const request = {
  5635. identifier: email,
  5636. continueUri
  5637. };
  5638. const { signinMethods } = await createAuthUri(util.getModularInstance(auth), request);
  5639. return signinMethods || [];
  5640. }
  5641. /**
  5642. * Sends a verification email to a user.
  5643. *
  5644. * @remarks
  5645. * The verification process is completed by calling {@link applyActionCode}.
  5646. *
  5647. * @example
  5648. * ```javascript
  5649. * const actionCodeSettings = {
  5650. * url: 'https://www.example.com/?email=user@example.com',
  5651. * iOS: {
  5652. * bundleId: 'com.example.ios'
  5653. * },
  5654. * android: {
  5655. * packageName: 'com.example.android',
  5656. * installApp: true,
  5657. * minimumVersion: '12'
  5658. * },
  5659. * handleCodeInApp: true
  5660. * };
  5661. * await sendEmailVerification(user, actionCodeSettings);
  5662. * // Obtain code from the user.
  5663. * await applyActionCode(auth, code);
  5664. * ```
  5665. *
  5666. * @param user - The user.
  5667. * @param actionCodeSettings - The {@link ActionCodeSettings}.
  5668. *
  5669. * @public
  5670. */
  5671. async function sendEmailVerification(user, actionCodeSettings) {
  5672. const userInternal = util.getModularInstance(user);
  5673. const idToken = await user.getIdToken();
  5674. const request = {
  5675. requestType: "VERIFY_EMAIL" /* ActionCodeOperation.VERIFY_EMAIL */,
  5676. idToken
  5677. };
  5678. if (actionCodeSettings) {
  5679. _setActionCodeSettingsOnRequest(userInternal.auth, request, actionCodeSettings);
  5680. }
  5681. const { email } = await sendEmailVerification$1(userInternal.auth, request);
  5682. if (email !== user.email) {
  5683. await user.reload();
  5684. }
  5685. }
  5686. /**
  5687. * Sends a verification email to a new email address.
  5688. *
  5689. * @remarks
  5690. * The user's email will be updated to the new one after being verified.
  5691. *
  5692. * If you have a custom email action handler, you can complete the verification process by calling
  5693. * {@link applyActionCode}.
  5694. *
  5695. * @example
  5696. * ```javascript
  5697. * const actionCodeSettings = {
  5698. * url: 'https://www.example.com/?email=user@example.com',
  5699. * iOS: {
  5700. * bundleId: 'com.example.ios'
  5701. * },
  5702. * android: {
  5703. * packageName: 'com.example.android',
  5704. * installApp: true,
  5705. * minimumVersion: '12'
  5706. * },
  5707. * handleCodeInApp: true
  5708. * };
  5709. * await verifyBeforeUpdateEmail(user, 'newemail@example.com', actionCodeSettings);
  5710. * // Obtain code from the user.
  5711. * await applyActionCode(auth, code);
  5712. * ```
  5713. *
  5714. * @param user - The user.
  5715. * @param newEmail - The new email address to be verified before update.
  5716. * @param actionCodeSettings - The {@link ActionCodeSettings}.
  5717. *
  5718. * @public
  5719. */
  5720. async function verifyBeforeUpdateEmail(user, newEmail, actionCodeSettings) {
  5721. const userInternal = util.getModularInstance(user);
  5722. const idToken = await user.getIdToken();
  5723. const request = {
  5724. requestType: "VERIFY_AND_CHANGE_EMAIL" /* ActionCodeOperation.VERIFY_AND_CHANGE_EMAIL */,
  5725. idToken,
  5726. newEmail
  5727. };
  5728. if (actionCodeSettings) {
  5729. _setActionCodeSettingsOnRequest(userInternal.auth, request, actionCodeSettings);
  5730. }
  5731. const { email } = await verifyAndChangeEmail(userInternal.auth, request);
  5732. if (email !== user.email) {
  5733. // If the local copy of the email on user is outdated, reload the
  5734. // user.
  5735. await user.reload();
  5736. }
  5737. }
  5738. /**
  5739. * @license
  5740. * Copyright 2020 Google LLC
  5741. *
  5742. * Licensed under the Apache License, Version 2.0 (the "License");
  5743. * you may not use this file except in compliance with the License.
  5744. * You may obtain a copy of the License at
  5745. *
  5746. * http://www.apache.org/licenses/LICENSE-2.0
  5747. *
  5748. * Unless required by applicable law or agreed to in writing, software
  5749. * distributed under the License is distributed on an "AS IS" BASIS,
  5750. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5751. * See the License for the specific language governing permissions and
  5752. * limitations under the License.
  5753. */
  5754. async function updateProfile$1(auth, request) {
  5755. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v1/accounts:update" /* Endpoint.SET_ACCOUNT_INFO */, request);
  5756. }
  5757. /**
  5758. * @license
  5759. * Copyright 2020 Google LLC
  5760. *
  5761. * Licensed under the Apache License, Version 2.0 (the "License");
  5762. * you may not use this file except in compliance with the License.
  5763. * You may obtain a copy of the License at
  5764. *
  5765. * http://www.apache.org/licenses/LICENSE-2.0
  5766. *
  5767. * Unless required by applicable law or agreed to in writing, software
  5768. * distributed under the License is distributed on an "AS IS" BASIS,
  5769. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5770. * See the License for the specific language governing permissions and
  5771. * limitations under the License.
  5772. */
  5773. /**
  5774. * Updates a user's profile data.
  5775. *
  5776. * @param user - The user.
  5777. * @param profile - The profile's `displayName` and `photoURL` to update.
  5778. *
  5779. * @public
  5780. */
  5781. async function updateProfile(user, { displayName, photoURL: photoUrl }) {
  5782. if (displayName === undefined && photoUrl === undefined) {
  5783. return;
  5784. }
  5785. const userInternal = util.getModularInstance(user);
  5786. const idToken = await userInternal.getIdToken();
  5787. const profileRequest = {
  5788. idToken,
  5789. displayName,
  5790. photoUrl,
  5791. returnSecureToken: true
  5792. };
  5793. const response = await _logoutIfInvalidated(userInternal, updateProfile$1(userInternal.auth, profileRequest));
  5794. userInternal.displayName = response.displayName || null;
  5795. userInternal.photoURL = response.photoUrl || null;
  5796. // Update the password provider as well
  5797. const passwordProvider = userInternal.providerData.find(({ providerId }) => providerId === "password" /* ProviderId.PASSWORD */);
  5798. if (passwordProvider) {
  5799. passwordProvider.displayName = userInternal.displayName;
  5800. passwordProvider.photoURL = userInternal.photoURL;
  5801. }
  5802. await userInternal._updateTokensIfNecessary(response);
  5803. }
  5804. /**
  5805. * Updates the user's email address.
  5806. *
  5807. * @remarks
  5808. * An email will be sent to the original email address (if it was set) that allows to revoke the
  5809. * email address change, in order to protect them from account hijacking.
  5810. *
  5811. * Important: this is a security sensitive operation that requires the user to have recently signed
  5812. * in. If this requirement isn't met, ask the user to authenticate again and then call
  5813. * {@link reauthenticateWithCredential}.
  5814. *
  5815. * @param user - The user.
  5816. * @param newEmail - The new email address.
  5817. *
  5818. * @public
  5819. */
  5820. function updateEmail(user, newEmail) {
  5821. return updateEmailOrPassword(util.getModularInstance(user), newEmail, null);
  5822. }
  5823. /**
  5824. * Updates the user's password.
  5825. *
  5826. * @remarks
  5827. * Important: this is a security sensitive operation that requires the user to have recently signed
  5828. * in. If this requirement isn't met, ask the user to authenticate again and then call
  5829. * {@link reauthenticateWithCredential}.
  5830. *
  5831. * @param user - The user.
  5832. * @param newPassword - The new password.
  5833. *
  5834. * @public
  5835. */
  5836. function updatePassword(user, newPassword) {
  5837. return updateEmailOrPassword(util.getModularInstance(user), null, newPassword);
  5838. }
  5839. async function updateEmailOrPassword(user, email, password) {
  5840. const { auth } = user;
  5841. const idToken = await user.getIdToken();
  5842. const request = {
  5843. idToken,
  5844. returnSecureToken: true
  5845. };
  5846. if (email) {
  5847. request.email = email;
  5848. }
  5849. if (password) {
  5850. request.password = password;
  5851. }
  5852. const response = await _logoutIfInvalidated(user, updateEmailPassword(auth, request));
  5853. await user._updateTokensIfNecessary(response, /* reload */ true);
  5854. }
  5855. /**
  5856. * @license
  5857. * Copyright 2019 Google LLC
  5858. *
  5859. * Licensed under the Apache License, Version 2.0 (the "License");
  5860. * you may not use this file except in compliance with the License.
  5861. * You may obtain a copy of the License at
  5862. *
  5863. * http://www.apache.org/licenses/LICENSE-2.0
  5864. *
  5865. * Unless required by applicable law or agreed to in writing, software
  5866. * distributed under the License is distributed on an "AS IS" BASIS,
  5867. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5868. * See the License for the specific language governing permissions and
  5869. * limitations under the License.
  5870. */
  5871. /**
  5872. * Parse the `AdditionalUserInfo` from the ID token response.
  5873. *
  5874. */
  5875. function _fromIdTokenResponse(idTokenResponse) {
  5876. var _a, _b;
  5877. if (!idTokenResponse) {
  5878. return null;
  5879. }
  5880. const { providerId } = idTokenResponse;
  5881. const profile = idTokenResponse.rawUserInfo
  5882. ? JSON.parse(idTokenResponse.rawUserInfo)
  5883. : {};
  5884. const isNewUser = idTokenResponse.isNewUser ||
  5885. idTokenResponse.kind === "identitytoolkit#SignupNewUserResponse" /* IdTokenResponseKind.SignupNewUser */;
  5886. if (!providerId && (idTokenResponse === null || idTokenResponse === void 0 ? void 0 : idTokenResponse.idToken)) {
  5887. const signInProvider = (_b = (_a = _parseToken(idTokenResponse.idToken)) === null || _a === void 0 ? void 0 : _a.firebase) === null || _b === void 0 ? void 0 : _b['sign_in_provider'];
  5888. if (signInProvider) {
  5889. const filteredProviderId = signInProvider !== "anonymous" /* ProviderId.ANONYMOUS */ &&
  5890. signInProvider !== "custom" /* ProviderId.CUSTOM */
  5891. ? signInProvider
  5892. : null;
  5893. // Uses generic class in accordance with the legacy SDK.
  5894. return new GenericAdditionalUserInfo(isNewUser, filteredProviderId);
  5895. }
  5896. }
  5897. if (!providerId) {
  5898. return null;
  5899. }
  5900. switch (providerId) {
  5901. case "facebook.com" /* ProviderId.FACEBOOK */:
  5902. return new FacebookAdditionalUserInfo(isNewUser, profile);
  5903. case "github.com" /* ProviderId.GITHUB */:
  5904. return new GithubAdditionalUserInfo(isNewUser, profile);
  5905. case "google.com" /* ProviderId.GOOGLE */:
  5906. return new GoogleAdditionalUserInfo(isNewUser, profile);
  5907. case "twitter.com" /* ProviderId.TWITTER */:
  5908. return new TwitterAdditionalUserInfo(isNewUser, profile, idTokenResponse.screenName || null);
  5909. case "custom" /* ProviderId.CUSTOM */:
  5910. case "anonymous" /* ProviderId.ANONYMOUS */:
  5911. return new GenericAdditionalUserInfo(isNewUser, null);
  5912. default:
  5913. return new GenericAdditionalUserInfo(isNewUser, providerId, profile);
  5914. }
  5915. }
  5916. class GenericAdditionalUserInfo {
  5917. constructor(isNewUser, providerId, profile = {}) {
  5918. this.isNewUser = isNewUser;
  5919. this.providerId = providerId;
  5920. this.profile = profile;
  5921. }
  5922. }
  5923. class FederatedAdditionalUserInfoWithUsername extends GenericAdditionalUserInfo {
  5924. constructor(isNewUser, providerId, profile, username) {
  5925. super(isNewUser, providerId, profile);
  5926. this.username = username;
  5927. }
  5928. }
  5929. class FacebookAdditionalUserInfo extends GenericAdditionalUserInfo {
  5930. constructor(isNewUser, profile) {
  5931. super(isNewUser, "facebook.com" /* ProviderId.FACEBOOK */, profile);
  5932. }
  5933. }
  5934. class GithubAdditionalUserInfo extends FederatedAdditionalUserInfoWithUsername {
  5935. constructor(isNewUser, profile) {
  5936. super(isNewUser, "github.com" /* ProviderId.GITHUB */, profile, typeof (profile === null || profile === void 0 ? void 0 : profile.login) === 'string' ? profile === null || profile === void 0 ? void 0 : profile.login : null);
  5937. }
  5938. }
  5939. class GoogleAdditionalUserInfo extends GenericAdditionalUserInfo {
  5940. constructor(isNewUser, profile) {
  5941. super(isNewUser, "google.com" /* ProviderId.GOOGLE */, profile);
  5942. }
  5943. }
  5944. class TwitterAdditionalUserInfo extends FederatedAdditionalUserInfoWithUsername {
  5945. constructor(isNewUser, profile, screenName) {
  5946. super(isNewUser, "twitter.com" /* ProviderId.TWITTER */, profile, screenName);
  5947. }
  5948. }
  5949. /**
  5950. * Extracts provider specific {@link AdditionalUserInfo} for the given credential.
  5951. *
  5952. * @param userCredential - The user credential.
  5953. *
  5954. * @public
  5955. */
  5956. function getAdditionalUserInfo(userCredential) {
  5957. const { user, _tokenResponse } = userCredential;
  5958. if (user.isAnonymous && !_tokenResponse) {
  5959. // Handle the special case where signInAnonymously() gets called twice.
  5960. // No network call is made so there's nothing to actually fill this in
  5961. return {
  5962. providerId: null,
  5963. isNewUser: false,
  5964. profile: null
  5965. };
  5966. }
  5967. return _fromIdTokenResponse(_tokenResponse);
  5968. }
  5969. /**
  5970. * @license
  5971. * Copyright 2020 Google LLC
  5972. *
  5973. * Licensed under the Apache License, Version 2.0 (the "License");
  5974. * you may not use this file except in compliance with the License.
  5975. * You may obtain a copy of the License at
  5976. *
  5977. * http://www.apache.org/licenses/LICENSE-2.0
  5978. *
  5979. * Unless required by applicable law or agreed to in writing, software
  5980. * distributed under the License is distributed on an "AS IS" BASIS,
  5981. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5982. * See the License for the specific language governing permissions and
  5983. * limitations under the License.
  5984. */
  5985. // Non-optional auth methods.
  5986. /**
  5987. * Changes the type of persistence on the {@link Auth} instance for the currently saved
  5988. * `Auth` session and applies this type of persistence for future sign-in requests, including
  5989. * sign-in with redirect requests.
  5990. *
  5991. * @remarks
  5992. * This makes it easy for a user signing in to specify whether their session should be
  5993. * remembered or not. It also makes it easier to never persist the `Auth` state for applications
  5994. * that are shared by other users or have sensitive data.
  5995. *
  5996. * @example
  5997. * ```javascript
  5998. * setPersistence(auth, browserSessionPersistence);
  5999. * ```
  6000. *
  6001. * @param auth - The {@link Auth} instance.
  6002. * @param persistence - The {@link Persistence} to use.
  6003. * @returns A `Promise` that resolves once the persistence change has completed
  6004. *
  6005. * @public
  6006. */
  6007. function setPersistence(auth, persistence) {
  6008. return util.getModularInstance(auth).setPersistence(persistence);
  6009. }
  6010. /**
  6011. * Loads the reCAPTCHA configuration into the `Auth` instance.
  6012. *
  6013. * @remarks
  6014. * This will load the reCAPTCHA config, which indicates whether the reCAPTCHA
  6015. * verification flow should be triggered for each auth provider, into the
  6016. * current Auth session.
  6017. *
  6018. * If initializeRecaptchaConfig() is not invoked, the auth flow will always start
  6019. * without reCAPTCHA verification. If the provider is configured to require reCAPTCHA
  6020. * verification, the SDK will transparently load the reCAPTCHA config and restart the
  6021. * auth flows.
  6022. *
  6023. * Thus, by calling this optional method, you will reduce the latency of future auth flows.
  6024. * Loading the reCAPTCHA config early will also enhance the signal collected by reCAPTCHA.
  6025. *
  6026. * @example
  6027. * ```javascript
  6028. * initializeRecaptchaConfig(auth);
  6029. * ```
  6030. *
  6031. * @param auth - The {@link Auth} instance.
  6032. *
  6033. * @public
  6034. */
  6035. function initializeRecaptchaConfig(auth) {
  6036. const authInternal = _castAuth(auth);
  6037. return authInternal.initializeRecaptchaConfig();
  6038. }
  6039. /**
  6040. * Adds an observer for changes to the signed-in user's ID token.
  6041. *
  6042. * @remarks
  6043. * This includes sign-in, sign-out, and token refresh events.
  6044. * This will not be triggered automatically upon ID token expiration. Use {@link User.getIdToken} to refresh the ID token.
  6045. *
  6046. * @param auth - The {@link Auth} instance.
  6047. * @param nextOrObserver - callback triggered on change.
  6048. * @param error - Deprecated. This callback is never triggered. Errors
  6049. * on signing in/out can be caught in promises returned from
  6050. * sign-in/sign-out functions.
  6051. * @param completed - Deprecated. This callback is never triggered.
  6052. *
  6053. * @public
  6054. */
  6055. function onIdTokenChanged(auth, nextOrObserver, error, completed) {
  6056. return util.getModularInstance(auth).onIdTokenChanged(nextOrObserver, error, completed);
  6057. }
  6058. /**
  6059. * Adds a blocking callback that runs before an auth state change
  6060. * sets a new user.
  6061. *
  6062. * @param auth - The {@link Auth} instance.
  6063. * @param callback - callback triggered before new user value is set.
  6064. * If this throws, it blocks the user from being set.
  6065. * @param onAbort - callback triggered if a later `beforeAuthStateChanged()`
  6066. * callback throws, allowing you to undo any side effects.
  6067. */
  6068. function beforeAuthStateChanged(auth, callback, onAbort) {
  6069. return util.getModularInstance(auth).beforeAuthStateChanged(callback, onAbort);
  6070. }
  6071. /**
  6072. * Adds an observer for changes to the user's sign-in state.
  6073. *
  6074. * @remarks
  6075. * To keep the old behavior, see {@link onIdTokenChanged}.
  6076. *
  6077. * @param auth - The {@link Auth} instance.
  6078. * @param nextOrObserver - callback triggered on change.
  6079. * @param error - Deprecated. This callback is never triggered. Errors
  6080. * on signing in/out can be caught in promises returned from
  6081. * sign-in/sign-out functions.
  6082. * @param completed - Deprecated. This callback is never triggered.
  6083. *
  6084. * @public
  6085. */
  6086. function onAuthStateChanged(auth, nextOrObserver, error, completed) {
  6087. return util.getModularInstance(auth).onAuthStateChanged(nextOrObserver, error, completed);
  6088. }
  6089. /**
  6090. * Sets the current language to the default device/browser preference.
  6091. *
  6092. * @param auth - The {@link Auth} instance.
  6093. *
  6094. * @public
  6095. */
  6096. function useDeviceLanguage(auth) {
  6097. util.getModularInstance(auth).useDeviceLanguage();
  6098. }
  6099. /**
  6100. * Asynchronously sets the provided user as {@link Auth.currentUser} on the
  6101. * {@link Auth} instance.
  6102. *
  6103. * @remarks
  6104. * A new instance copy of the user provided will be made and set as currentUser.
  6105. *
  6106. * This will trigger {@link onAuthStateChanged} and {@link onIdTokenChanged} listeners
  6107. * like other sign in methods.
  6108. *
  6109. * The operation fails with an error if the user to be updated belongs to a different Firebase
  6110. * project.
  6111. *
  6112. * @param auth - The {@link Auth} instance.
  6113. * @param user - The new {@link User}.
  6114. *
  6115. * @public
  6116. */
  6117. function updateCurrentUser(auth, user) {
  6118. return util.getModularInstance(auth).updateCurrentUser(user);
  6119. }
  6120. /**
  6121. * Signs out the current user.
  6122. *
  6123. * @param auth - The {@link Auth} instance.
  6124. *
  6125. * @public
  6126. */
  6127. function signOut(auth) {
  6128. return util.getModularInstance(auth).signOut();
  6129. }
  6130. /**
  6131. * Deletes and signs out the user.
  6132. *
  6133. * @remarks
  6134. * Important: this is a security-sensitive operation that requires the user to have recently
  6135. * signed in. If this requirement isn't met, ask the user to authenticate again and then call
  6136. * {@link reauthenticateWithCredential}.
  6137. *
  6138. * @param user - The user.
  6139. *
  6140. * @public
  6141. */
  6142. async function deleteUser(user) {
  6143. return util.getModularInstance(user).delete();
  6144. }
  6145. class MultiFactorSessionImpl {
  6146. constructor(type, credential, auth) {
  6147. this.type = type;
  6148. this.credential = credential;
  6149. this.auth = auth;
  6150. }
  6151. static _fromIdtoken(idToken, auth) {
  6152. return new MultiFactorSessionImpl("enroll" /* MultiFactorSessionType.ENROLL */, idToken, auth);
  6153. }
  6154. static _fromMfaPendingCredential(mfaPendingCredential) {
  6155. return new MultiFactorSessionImpl("signin" /* MultiFactorSessionType.SIGN_IN */, mfaPendingCredential);
  6156. }
  6157. toJSON() {
  6158. const key = this.type === "enroll" /* MultiFactorSessionType.ENROLL */
  6159. ? 'idToken'
  6160. : 'pendingCredential';
  6161. return {
  6162. multiFactorSession: {
  6163. [key]: this.credential
  6164. }
  6165. };
  6166. }
  6167. static fromJSON(obj) {
  6168. var _a, _b;
  6169. if (obj === null || obj === void 0 ? void 0 : obj.multiFactorSession) {
  6170. if ((_a = obj.multiFactorSession) === null || _a === void 0 ? void 0 : _a.pendingCredential) {
  6171. return MultiFactorSessionImpl._fromMfaPendingCredential(obj.multiFactorSession.pendingCredential);
  6172. }
  6173. else if ((_b = obj.multiFactorSession) === null || _b === void 0 ? void 0 : _b.idToken) {
  6174. return MultiFactorSessionImpl._fromIdtoken(obj.multiFactorSession.idToken);
  6175. }
  6176. }
  6177. return null;
  6178. }
  6179. }
  6180. /**
  6181. * @license
  6182. * Copyright 2020 Google LLC
  6183. *
  6184. * Licensed under the Apache License, Version 2.0 (the "License");
  6185. * you may not use this file except in compliance with the License.
  6186. * You may obtain a copy of the License at
  6187. *
  6188. * http://www.apache.org/licenses/LICENSE-2.0
  6189. *
  6190. * Unless required by applicable law or agreed to in writing, software
  6191. * distributed under the License is distributed on an "AS IS" BASIS,
  6192. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6193. * See the License for the specific language governing permissions and
  6194. * limitations under the License.
  6195. */
  6196. class MultiFactorResolverImpl {
  6197. constructor(session, hints, signInResolver) {
  6198. this.session = session;
  6199. this.hints = hints;
  6200. this.signInResolver = signInResolver;
  6201. }
  6202. /** @internal */
  6203. static _fromError(authExtern, error) {
  6204. const auth = _castAuth(authExtern);
  6205. const serverResponse = error.customData._serverResponse;
  6206. const hints = (serverResponse.mfaInfo || []).map(enrollment => MultiFactorInfoImpl._fromServerResponse(auth, enrollment));
  6207. _assert(serverResponse.mfaPendingCredential, auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  6208. const session = MultiFactorSessionImpl._fromMfaPendingCredential(serverResponse.mfaPendingCredential);
  6209. return new MultiFactorResolverImpl(session, hints, async (assertion) => {
  6210. const mfaResponse = await assertion._process(auth, session);
  6211. // Clear out the unneeded fields from the old login response
  6212. delete serverResponse.mfaInfo;
  6213. delete serverResponse.mfaPendingCredential;
  6214. // Use in the new token & refresh token in the old response
  6215. const idTokenResponse = Object.assign(Object.assign({}, serverResponse), { idToken: mfaResponse.idToken, refreshToken: mfaResponse.refreshToken });
  6216. // TODO: we should collapse this switch statement into UserCredentialImpl._forOperation and have it support the SIGN_IN case
  6217. switch (error.operationType) {
  6218. case "signIn" /* OperationType.SIGN_IN */:
  6219. const userCredential = await UserCredentialImpl._fromIdTokenResponse(auth, error.operationType, idTokenResponse);
  6220. await auth._updateCurrentUser(userCredential.user);
  6221. return userCredential;
  6222. case "reauthenticate" /* OperationType.REAUTHENTICATE */:
  6223. _assert(error.user, auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  6224. return UserCredentialImpl._forOperation(error.user, error.operationType, idTokenResponse);
  6225. default:
  6226. _fail(auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  6227. }
  6228. });
  6229. }
  6230. async resolveSignIn(assertionExtern) {
  6231. const assertion = assertionExtern;
  6232. return this.signInResolver(assertion);
  6233. }
  6234. }
  6235. /**
  6236. * Provides a {@link MultiFactorResolver} suitable for completion of a
  6237. * multi-factor flow.
  6238. *
  6239. * @param auth - The {@link Auth} instance.
  6240. * @param error - The {@link MultiFactorError} raised during a sign-in, or
  6241. * reauthentication operation.
  6242. *
  6243. * @public
  6244. */
  6245. function getMultiFactorResolver(auth, error) {
  6246. var _a;
  6247. const authModular = util.getModularInstance(auth);
  6248. const errorInternal = error;
  6249. _assert(error.customData.operationType, authModular, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  6250. _assert((_a = errorInternal.customData._serverResponse) === null || _a === void 0 ? void 0 : _a.mfaPendingCredential, authModular, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  6251. return MultiFactorResolverImpl._fromError(authModular, errorInternal);
  6252. }
  6253. /**
  6254. * @license
  6255. * Copyright 2020 Google LLC
  6256. *
  6257. * Licensed under the Apache License, Version 2.0 (the "License");
  6258. * you may not use this file except in compliance with the License.
  6259. * You may obtain a copy of the License at
  6260. *
  6261. * http://www.apache.org/licenses/LICENSE-2.0
  6262. *
  6263. * Unless required by applicable law or agreed to in writing, software
  6264. * distributed under the License is distributed on an "AS IS" BASIS,
  6265. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6266. * See the License for the specific language governing permissions and
  6267. * limitations under the License.
  6268. */
  6269. function startEnrollPhoneMfa(auth, request) {
  6270. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v2/accounts/mfaEnrollment:start" /* Endpoint.START_MFA_ENROLLMENT */, _addTidIfNecessary(auth, request));
  6271. }
  6272. function finalizeEnrollPhoneMfa(auth, request) {
  6273. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v2/accounts/mfaEnrollment:finalize" /* Endpoint.FINALIZE_MFA_ENROLLMENT */, _addTidIfNecessary(auth, request));
  6274. }
  6275. function startEnrollTotpMfa(auth, request) {
  6276. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v2/accounts/mfaEnrollment:start" /* Endpoint.START_MFA_ENROLLMENT */, _addTidIfNecessary(auth, request));
  6277. }
  6278. function finalizeEnrollTotpMfa(auth, request) {
  6279. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v2/accounts/mfaEnrollment:finalize" /* Endpoint.FINALIZE_MFA_ENROLLMENT */, _addTidIfNecessary(auth, request));
  6280. }
  6281. function withdrawMfa(auth, request) {
  6282. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v2/accounts/mfaEnrollment:withdraw" /* Endpoint.WITHDRAW_MFA */, _addTidIfNecessary(auth, request));
  6283. }
  6284. class MultiFactorUserImpl {
  6285. constructor(user) {
  6286. this.user = user;
  6287. this.enrolledFactors = [];
  6288. user._onReload(userInfo => {
  6289. if (userInfo.mfaInfo) {
  6290. this.enrolledFactors = userInfo.mfaInfo.map(enrollment => MultiFactorInfoImpl._fromServerResponse(user.auth, enrollment));
  6291. }
  6292. });
  6293. }
  6294. static _fromUser(user) {
  6295. return new MultiFactorUserImpl(user);
  6296. }
  6297. async getSession() {
  6298. return MultiFactorSessionImpl._fromIdtoken(await this.user.getIdToken(), this.user.auth);
  6299. }
  6300. async enroll(assertionExtern, displayName) {
  6301. const assertion = assertionExtern;
  6302. const session = (await this.getSession());
  6303. const finalizeMfaResponse = await _logoutIfInvalidated(this.user, assertion._process(this.user.auth, session, displayName));
  6304. // New tokens will be issued after enrollment of the new second factors.
  6305. // They need to be updated on the user.
  6306. await this.user._updateTokensIfNecessary(finalizeMfaResponse);
  6307. // The user needs to be reloaded to get the new multi-factor information
  6308. // from server. USER_RELOADED event will be triggered and `enrolledFactors`
  6309. // will be updated.
  6310. return this.user.reload();
  6311. }
  6312. async unenroll(infoOrUid) {
  6313. const mfaEnrollmentId = typeof infoOrUid === 'string' ? infoOrUid : infoOrUid.uid;
  6314. const idToken = await this.user.getIdToken();
  6315. try {
  6316. const idTokenResponse = await _logoutIfInvalidated(this.user, withdrawMfa(this.user.auth, {
  6317. idToken,
  6318. mfaEnrollmentId
  6319. }));
  6320. // Remove the second factor from the user's list.
  6321. this.enrolledFactors = this.enrolledFactors.filter(({ uid }) => uid !== mfaEnrollmentId);
  6322. // Depending on whether the backend decided to revoke the user's session,
  6323. // the tokenResponse may be empty. If the tokens were not updated (and they
  6324. // are now invalid), reloading the user will discover this and invalidate
  6325. // the user's state accordingly.
  6326. await this.user._updateTokensIfNecessary(idTokenResponse);
  6327. await this.user.reload();
  6328. }
  6329. catch (e) {
  6330. throw e;
  6331. }
  6332. }
  6333. }
  6334. const multiFactorUserCache = new WeakMap();
  6335. /**
  6336. * The {@link MultiFactorUser} corresponding to the user.
  6337. *
  6338. * @remarks
  6339. * This is used to access all multi-factor properties and operations related to the user.
  6340. *
  6341. * @param user - The user.
  6342. *
  6343. * @public
  6344. */
  6345. function multiFactor(user) {
  6346. const userModular = util.getModularInstance(user);
  6347. if (!multiFactorUserCache.has(userModular)) {
  6348. multiFactorUserCache.set(userModular, MultiFactorUserImpl._fromUser(userModular));
  6349. }
  6350. return multiFactorUserCache.get(userModular);
  6351. }
  6352. const STORAGE_AVAILABLE_KEY = '__sak';
  6353. /**
  6354. * @license
  6355. * Copyright 2019 Google LLC
  6356. *
  6357. * Licensed under the Apache License, Version 2.0 (the "License");
  6358. * you may not use this file except in compliance with the License.
  6359. * You may obtain a copy of the License at
  6360. *
  6361. * http://www.apache.org/licenses/LICENSE-2.0
  6362. *
  6363. * Unless required by applicable law or agreed to in writing, software
  6364. * distributed under the License is distributed on an "AS IS" BASIS,
  6365. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6366. * See the License for the specific language governing permissions and
  6367. * limitations under the License.
  6368. */
  6369. // There are two different browser persistence types: local and session.
  6370. // Both have the same implementation but use a different underlying storage
  6371. // object.
  6372. class BrowserPersistenceClass {
  6373. constructor(storageRetriever, type) {
  6374. this.storageRetriever = storageRetriever;
  6375. this.type = type;
  6376. }
  6377. _isAvailable() {
  6378. try {
  6379. if (!this.storage) {
  6380. return Promise.resolve(false);
  6381. }
  6382. this.storage.setItem(STORAGE_AVAILABLE_KEY, '1');
  6383. this.storage.removeItem(STORAGE_AVAILABLE_KEY);
  6384. return Promise.resolve(true);
  6385. }
  6386. catch (_a) {
  6387. return Promise.resolve(false);
  6388. }
  6389. }
  6390. _set(key, value) {
  6391. this.storage.setItem(key, JSON.stringify(value));
  6392. return Promise.resolve();
  6393. }
  6394. _get(key) {
  6395. const json = this.storage.getItem(key);
  6396. return Promise.resolve(json ? JSON.parse(json) : null);
  6397. }
  6398. _remove(key) {
  6399. this.storage.removeItem(key);
  6400. return Promise.resolve();
  6401. }
  6402. get storage() {
  6403. return this.storageRetriever();
  6404. }
  6405. }
  6406. /**
  6407. * @license
  6408. * Copyright 2020 Google LLC
  6409. *
  6410. * Licensed under the Apache License, Version 2.0 (the "License");
  6411. * you may not use this file except in compliance with the License.
  6412. * You may obtain a copy of the License at
  6413. *
  6414. * http://www.apache.org/licenses/LICENSE-2.0
  6415. *
  6416. * Unless required by applicable law or agreed to in writing, software
  6417. * distributed under the License is distributed on an "AS IS" BASIS,
  6418. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6419. * See the License for the specific language governing permissions and
  6420. * limitations under the License.
  6421. */
  6422. function _iframeCannotSyncWebStorage() {
  6423. const ua = util.getUA();
  6424. return _isSafari(ua) || _isIOS(ua);
  6425. }
  6426. // The polling period in case events are not supported
  6427. const _POLLING_INTERVAL_MS$1 = 1000;
  6428. // The IE 10 localStorage cross tab synchronization delay in milliseconds
  6429. const IE10_LOCAL_STORAGE_SYNC_DELAY = 10;
  6430. class BrowserLocalPersistence extends BrowserPersistenceClass {
  6431. constructor() {
  6432. super(() => window.localStorage, "LOCAL" /* PersistenceType.LOCAL */);
  6433. this.boundEventHandler = (event, poll) => this.onStorageEvent(event, poll);
  6434. this.listeners = {};
  6435. this.localCache = {};
  6436. // setTimeout return value is platform specific
  6437. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  6438. this.pollTimer = null;
  6439. // Safari or iOS browser and embedded in an iframe.
  6440. this.safariLocalStorageNotSynced = _iframeCannotSyncWebStorage() && _isIframe();
  6441. // Whether to use polling instead of depending on window events
  6442. this.fallbackToPolling = _isMobileBrowser();
  6443. this._shouldAllowMigration = true;
  6444. }
  6445. forAllChangedKeys(cb) {
  6446. // Check all keys with listeners on them.
  6447. for (const key of Object.keys(this.listeners)) {
  6448. // Get value from localStorage.
  6449. const newValue = this.storage.getItem(key);
  6450. const oldValue = this.localCache[key];
  6451. // If local map value does not match, trigger listener with storage event.
  6452. // Differentiate this simulated event from the real storage event.
  6453. if (newValue !== oldValue) {
  6454. cb(key, oldValue, newValue);
  6455. }
  6456. }
  6457. }
  6458. onStorageEvent(event, poll = false) {
  6459. // Key would be null in some situations, like when localStorage is cleared
  6460. if (!event.key) {
  6461. this.forAllChangedKeys((key, _oldValue, newValue) => {
  6462. this.notifyListeners(key, newValue);
  6463. });
  6464. return;
  6465. }
  6466. const key = event.key;
  6467. // Check the mechanism how this event was detected.
  6468. // The first event will dictate the mechanism to be used.
  6469. if (poll) {
  6470. // Environment detects storage changes via polling.
  6471. // Remove storage event listener to prevent possible event duplication.
  6472. this.detachListener();
  6473. }
  6474. else {
  6475. // Environment detects storage changes via storage event listener.
  6476. // Remove polling listener to prevent possible event duplication.
  6477. this.stopPolling();
  6478. }
  6479. // Safari embedded iframe. Storage event will trigger with the delta
  6480. // changes but no changes will be applied to the iframe localStorage.
  6481. if (this.safariLocalStorageNotSynced) {
  6482. // Get current iframe page value.
  6483. const storedValue = this.storage.getItem(key);
  6484. // Value not synchronized, synchronize manually.
  6485. if (event.newValue !== storedValue) {
  6486. if (event.newValue !== null) {
  6487. // Value changed from current value.
  6488. this.storage.setItem(key, event.newValue);
  6489. }
  6490. else {
  6491. // Current value deleted.
  6492. this.storage.removeItem(key);
  6493. }
  6494. }
  6495. else if (this.localCache[key] === event.newValue && !poll) {
  6496. // Already detected and processed, do not trigger listeners again.
  6497. return;
  6498. }
  6499. }
  6500. const triggerListeners = () => {
  6501. // Keep local map up to date in case storage event is triggered before
  6502. // poll.
  6503. const storedValue = this.storage.getItem(key);
  6504. if (!poll && this.localCache[key] === storedValue) {
  6505. // Real storage event which has already been detected, do nothing.
  6506. // This seems to trigger in some IE browsers for some reason.
  6507. return;
  6508. }
  6509. this.notifyListeners(key, storedValue);
  6510. };
  6511. const storedValue = this.storage.getItem(key);
  6512. if (_isIE10() &&
  6513. storedValue !== event.newValue &&
  6514. event.newValue !== event.oldValue) {
  6515. // IE 10 has this weird bug where a storage event would trigger with the
  6516. // correct key, oldValue and newValue but localStorage.getItem(key) does
  6517. // not yield the updated value until a few milliseconds. This ensures
  6518. // this recovers from that situation.
  6519. setTimeout(triggerListeners, IE10_LOCAL_STORAGE_SYNC_DELAY);
  6520. }
  6521. else {
  6522. triggerListeners();
  6523. }
  6524. }
  6525. notifyListeners(key, value) {
  6526. this.localCache[key] = value;
  6527. const listeners = this.listeners[key];
  6528. if (listeners) {
  6529. for (const listener of Array.from(listeners)) {
  6530. listener(value ? JSON.parse(value) : value);
  6531. }
  6532. }
  6533. }
  6534. startPolling() {
  6535. this.stopPolling();
  6536. this.pollTimer = setInterval(() => {
  6537. this.forAllChangedKeys((key, oldValue, newValue) => {
  6538. this.onStorageEvent(new StorageEvent('storage', {
  6539. key,
  6540. oldValue,
  6541. newValue
  6542. }),
  6543. /* poll */ true);
  6544. });
  6545. }, _POLLING_INTERVAL_MS$1);
  6546. }
  6547. stopPolling() {
  6548. if (this.pollTimer) {
  6549. clearInterval(this.pollTimer);
  6550. this.pollTimer = null;
  6551. }
  6552. }
  6553. attachListener() {
  6554. window.addEventListener('storage', this.boundEventHandler);
  6555. }
  6556. detachListener() {
  6557. window.removeEventListener('storage', this.boundEventHandler);
  6558. }
  6559. _addListener(key, listener) {
  6560. if (Object.keys(this.listeners).length === 0) {
  6561. // Whether browser can detect storage event when it had already been pushed to the background.
  6562. // This may happen in some mobile browsers. A localStorage change in the foreground window
  6563. // will not be detected in the background window via the storage event.
  6564. // This was detected in iOS 7.x mobile browsers
  6565. if (this.fallbackToPolling) {
  6566. this.startPolling();
  6567. }
  6568. else {
  6569. this.attachListener();
  6570. }
  6571. }
  6572. if (!this.listeners[key]) {
  6573. this.listeners[key] = new Set();
  6574. // Populate the cache to avoid spuriously triggering on first poll.
  6575. this.localCache[key] = this.storage.getItem(key);
  6576. }
  6577. this.listeners[key].add(listener);
  6578. }
  6579. _removeListener(key, listener) {
  6580. if (this.listeners[key]) {
  6581. this.listeners[key].delete(listener);
  6582. if (this.listeners[key].size === 0) {
  6583. delete this.listeners[key];
  6584. }
  6585. }
  6586. if (Object.keys(this.listeners).length === 0) {
  6587. this.detachListener();
  6588. this.stopPolling();
  6589. }
  6590. }
  6591. // Update local cache on base operations:
  6592. async _set(key, value) {
  6593. await super._set(key, value);
  6594. this.localCache[key] = JSON.stringify(value);
  6595. }
  6596. async _get(key) {
  6597. const value = await super._get(key);
  6598. this.localCache[key] = JSON.stringify(value);
  6599. return value;
  6600. }
  6601. async _remove(key) {
  6602. await super._remove(key);
  6603. delete this.localCache[key];
  6604. }
  6605. }
  6606. BrowserLocalPersistence.type = 'LOCAL';
  6607. /**
  6608. * An implementation of {@link Persistence} of type `LOCAL` using `localStorage`
  6609. * for the underlying storage.
  6610. *
  6611. * @public
  6612. */
  6613. const browserLocalPersistence = BrowserLocalPersistence;
  6614. /**
  6615. * @license
  6616. * Copyright 2020 Google LLC
  6617. *
  6618. * Licensed under the Apache License, Version 2.0 (the "License");
  6619. * you may not use this file except in compliance with the License.
  6620. * You may obtain a copy of the License at
  6621. *
  6622. * http://www.apache.org/licenses/LICENSE-2.0
  6623. *
  6624. * Unless required by applicable law or agreed to in writing, software
  6625. * distributed under the License is distributed on an "AS IS" BASIS,
  6626. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6627. * See the License for the specific language governing permissions and
  6628. * limitations under the License.
  6629. */
  6630. class BrowserSessionPersistence extends BrowserPersistenceClass {
  6631. constructor() {
  6632. super(() => window.sessionStorage, "SESSION" /* PersistenceType.SESSION */);
  6633. }
  6634. _addListener(_key, _listener) {
  6635. // Listeners are not supported for session storage since it cannot be shared across windows
  6636. return;
  6637. }
  6638. _removeListener(_key, _listener) {
  6639. // Listeners are not supported for session storage since it cannot be shared across windows
  6640. return;
  6641. }
  6642. }
  6643. BrowserSessionPersistence.type = 'SESSION';
  6644. /**
  6645. * An implementation of {@link Persistence} of `SESSION` using `sessionStorage`
  6646. * for the underlying storage.
  6647. *
  6648. * @public
  6649. */
  6650. const browserSessionPersistence = BrowserSessionPersistence;
  6651. /**
  6652. * @license
  6653. * Copyright 2019 Google LLC
  6654. *
  6655. * Licensed under the Apache License, Version 2.0 (the "License");
  6656. * you may not use this file except in compliance with the License.
  6657. * You may obtain a copy of the License at
  6658. *
  6659. * http://www.apache.org/licenses/LICENSE-2.0
  6660. *
  6661. * Unless required by applicable law or agreed to in writing, software
  6662. * distributed under the License is distributed on an "AS IS" BASIS,
  6663. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6664. * See the License for the specific language governing permissions and
  6665. * limitations under the License.
  6666. */
  6667. /**
  6668. * Shim for Promise.allSettled, note the slightly different format of `fulfilled` vs `status`.
  6669. *
  6670. * @param promises - Array of promises to wait on.
  6671. */
  6672. function _allSettled(promises) {
  6673. return Promise.all(promises.map(async (promise) => {
  6674. try {
  6675. const value = await promise;
  6676. return {
  6677. fulfilled: true,
  6678. value
  6679. };
  6680. }
  6681. catch (reason) {
  6682. return {
  6683. fulfilled: false,
  6684. reason
  6685. };
  6686. }
  6687. }));
  6688. }
  6689. /**
  6690. * @license
  6691. * Copyright 2019 Google LLC
  6692. *
  6693. * Licensed under the Apache License, Version 2.0 (the "License");
  6694. * you may not use this file except in compliance with the License.
  6695. * You may obtain a copy of the License at
  6696. *
  6697. * http://www.apache.org/licenses/LICENSE-2.0
  6698. *
  6699. * Unless required by applicable law or agreed to in writing, software
  6700. * distributed under the License is distributed on an "AS IS" BASIS,
  6701. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6702. * See the License for the specific language governing permissions and
  6703. * limitations under the License.
  6704. */
  6705. /**
  6706. * Interface class for receiving messages.
  6707. *
  6708. */
  6709. class Receiver {
  6710. constructor(eventTarget) {
  6711. this.eventTarget = eventTarget;
  6712. this.handlersMap = {};
  6713. this.boundEventHandler = this.handleEvent.bind(this);
  6714. }
  6715. /**
  6716. * Obtain an instance of a Receiver for a given event target, if none exists it will be created.
  6717. *
  6718. * @param eventTarget - An event target (such as window or self) through which the underlying
  6719. * messages will be received.
  6720. */
  6721. static _getInstance(eventTarget) {
  6722. // The results are stored in an array since objects can't be keys for other
  6723. // objects. In addition, setting a unique property on an event target as a
  6724. // hash map key may not be allowed due to CORS restrictions.
  6725. const existingInstance = this.receivers.find(receiver => receiver.isListeningto(eventTarget));
  6726. if (existingInstance) {
  6727. return existingInstance;
  6728. }
  6729. const newInstance = new Receiver(eventTarget);
  6730. this.receivers.push(newInstance);
  6731. return newInstance;
  6732. }
  6733. isListeningto(eventTarget) {
  6734. return this.eventTarget === eventTarget;
  6735. }
  6736. /**
  6737. * Fans out a MessageEvent to the appropriate listeners.
  6738. *
  6739. * @remarks
  6740. * Sends an {@link Status.ACK} upon receipt and a {@link Status.DONE} once all handlers have
  6741. * finished processing.
  6742. *
  6743. * @param event - The MessageEvent.
  6744. *
  6745. */
  6746. async handleEvent(event) {
  6747. const messageEvent = event;
  6748. const { eventId, eventType, data } = messageEvent.data;
  6749. const handlers = this.handlersMap[eventType];
  6750. if (!(handlers === null || handlers === void 0 ? void 0 : handlers.size)) {
  6751. return;
  6752. }
  6753. messageEvent.ports[0].postMessage({
  6754. status: "ack" /* _Status.ACK */,
  6755. eventId,
  6756. eventType
  6757. });
  6758. const promises = Array.from(handlers).map(async (handler) => handler(messageEvent.origin, data));
  6759. const response = await _allSettled(promises);
  6760. messageEvent.ports[0].postMessage({
  6761. status: "done" /* _Status.DONE */,
  6762. eventId,
  6763. eventType,
  6764. response
  6765. });
  6766. }
  6767. /**
  6768. * Subscribe an event handler for a particular event.
  6769. *
  6770. * @param eventType - Event name to subscribe to.
  6771. * @param eventHandler - The event handler which should receive the events.
  6772. *
  6773. */
  6774. _subscribe(eventType, eventHandler) {
  6775. if (Object.keys(this.handlersMap).length === 0) {
  6776. this.eventTarget.addEventListener('message', this.boundEventHandler);
  6777. }
  6778. if (!this.handlersMap[eventType]) {
  6779. this.handlersMap[eventType] = new Set();
  6780. }
  6781. this.handlersMap[eventType].add(eventHandler);
  6782. }
  6783. /**
  6784. * Unsubscribe an event handler from a particular event.
  6785. *
  6786. * @param eventType - Event name to unsubscribe from.
  6787. * @param eventHandler - Optinoal event handler, if none provided, unsubscribe all handlers on this event.
  6788. *
  6789. */
  6790. _unsubscribe(eventType, eventHandler) {
  6791. if (this.handlersMap[eventType] && eventHandler) {
  6792. this.handlersMap[eventType].delete(eventHandler);
  6793. }
  6794. if (!eventHandler || this.handlersMap[eventType].size === 0) {
  6795. delete this.handlersMap[eventType];
  6796. }
  6797. if (Object.keys(this.handlersMap).length === 0) {
  6798. this.eventTarget.removeEventListener('message', this.boundEventHandler);
  6799. }
  6800. }
  6801. }
  6802. Receiver.receivers = [];
  6803. /**
  6804. * @license
  6805. * Copyright 2020 Google LLC
  6806. *
  6807. * Licensed under the Apache License, Version 2.0 (the "License");
  6808. * you may not use this file except in compliance with the License.
  6809. * You may obtain a copy of the License at
  6810. *
  6811. * http://www.apache.org/licenses/LICENSE-2.0
  6812. *
  6813. * Unless required by applicable law or agreed to in writing, software
  6814. * distributed under the License is distributed on an "AS IS" BASIS,
  6815. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6816. * See the License for the specific language governing permissions and
  6817. * limitations under the License.
  6818. */
  6819. function _generateEventId(prefix = '', digits = 10) {
  6820. let random = '';
  6821. for (let i = 0; i < digits; i++) {
  6822. random += Math.floor(Math.random() * 10);
  6823. }
  6824. return prefix + random;
  6825. }
  6826. /**
  6827. * @license
  6828. * Copyright 2019 Google LLC
  6829. *
  6830. * Licensed under the Apache License, Version 2.0 (the "License");
  6831. * you may not use this file except in compliance with the License.
  6832. * You may obtain a copy of the License at
  6833. *
  6834. * http://www.apache.org/licenses/LICENSE-2.0
  6835. *
  6836. * Unless required by applicable law or agreed to in writing, software
  6837. * distributed under the License is distributed on an "AS IS" BASIS,
  6838. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6839. * See the License for the specific language governing permissions and
  6840. * limitations under the License.
  6841. */
  6842. /**
  6843. * Interface for sending messages and waiting for a completion response.
  6844. *
  6845. */
  6846. class Sender {
  6847. constructor(target) {
  6848. this.target = target;
  6849. this.handlers = new Set();
  6850. }
  6851. /**
  6852. * Unsubscribe the handler and remove it from our tracking Set.
  6853. *
  6854. * @param handler - The handler to unsubscribe.
  6855. */
  6856. removeMessageHandler(handler) {
  6857. if (handler.messageChannel) {
  6858. handler.messageChannel.port1.removeEventListener('message', handler.onMessage);
  6859. handler.messageChannel.port1.close();
  6860. }
  6861. this.handlers.delete(handler);
  6862. }
  6863. /**
  6864. * Send a message to the Receiver located at {@link target}.
  6865. *
  6866. * @remarks
  6867. * We'll first wait a bit for an ACK , if we get one we will wait significantly longer until the
  6868. * receiver has had a chance to fully process the event.
  6869. *
  6870. * @param eventType - Type of event to send.
  6871. * @param data - The payload of the event.
  6872. * @param timeout - Timeout for waiting on an ACK from the receiver.
  6873. *
  6874. * @returns An array of settled promises from all the handlers that were listening on the receiver.
  6875. */
  6876. async _send(eventType, data, timeout = 50 /* _TimeoutDuration.ACK */) {
  6877. const messageChannel = typeof MessageChannel !== 'undefined' ? new MessageChannel() : null;
  6878. if (!messageChannel) {
  6879. throw new Error("connection_unavailable" /* _MessageError.CONNECTION_UNAVAILABLE */);
  6880. }
  6881. // Node timers and browser timers return fundamentally different types.
  6882. // We don't actually care what the value is but TS won't accept unknown and
  6883. // we can't cast properly in both environments.
  6884. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  6885. let completionTimer;
  6886. let handler;
  6887. return new Promise((resolve, reject) => {
  6888. const eventId = _generateEventId('', 20);
  6889. messageChannel.port1.start();
  6890. const ackTimer = setTimeout(() => {
  6891. reject(new Error("unsupported_event" /* _MessageError.UNSUPPORTED_EVENT */));
  6892. }, timeout);
  6893. handler = {
  6894. messageChannel,
  6895. onMessage(event) {
  6896. const messageEvent = event;
  6897. if (messageEvent.data.eventId !== eventId) {
  6898. return;
  6899. }
  6900. switch (messageEvent.data.status) {
  6901. case "ack" /* _Status.ACK */:
  6902. // The receiver should ACK first.
  6903. clearTimeout(ackTimer);
  6904. completionTimer = setTimeout(() => {
  6905. reject(new Error("timeout" /* _MessageError.TIMEOUT */));
  6906. }, 3000 /* _TimeoutDuration.COMPLETION */);
  6907. break;
  6908. case "done" /* _Status.DONE */:
  6909. // Once the receiver's handlers are finished we will get the results.
  6910. clearTimeout(completionTimer);
  6911. resolve(messageEvent.data.response);
  6912. break;
  6913. default:
  6914. clearTimeout(ackTimer);
  6915. clearTimeout(completionTimer);
  6916. reject(new Error("invalid_response" /* _MessageError.INVALID_RESPONSE */));
  6917. break;
  6918. }
  6919. }
  6920. };
  6921. this.handlers.add(handler);
  6922. messageChannel.port1.addEventListener('message', handler.onMessage);
  6923. this.target.postMessage({
  6924. eventType,
  6925. eventId,
  6926. data
  6927. }, [messageChannel.port2]);
  6928. }).finally(() => {
  6929. if (handler) {
  6930. this.removeMessageHandler(handler);
  6931. }
  6932. });
  6933. }
  6934. }
  6935. /**
  6936. * @license
  6937. * Copyright 2020 Google LLC
  6938. *
  6939. * Licensed under the Apache License, Version 2.0 (the "License");
  6940. * you may not use this file except in compliance with the License.
  6941. * You may obtain a copy of the License at
  6942. *
  6943. * http://www.apache.org/licenses/LICENSE-2.0
  6944. *
  6945. * Unless required by applicable law or agreed to in writing, software
  6946. * distributed under the License is distributed on an "AS IS" BASIS,
  6947. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6948. * See the License for the specific language governing permissions and
  6949. * limitations under the License.
  6950. */
  6951. /**
  6952. * Lazy accessor for window, since the compat layer won't tree shake this out,
  6953. * we need to make sure not to mess with window unless we have to
  6954. */
  6955. function _window() {
  6956. return window;
  6957. }
  6958. function _setWindowLocation(url) {
  6959. _window().location.href = url;
  6960. }
  6961. /**
  6962. * @license
  6963. * Copyright 2020 Google LLC.
  6964. *
  6965. * Licensed under the Apache License, Version 2.0 (the "License");
  6966. * you may not use this file except in compliance with the License.
  6967. * You may obtain a copy of the License at
  6968. *
  6969. * http://www.apache.org/licenses/LICENSE-2.0
  6970. *
  6971. * Unless required by applicable law or agreed to in writing, software
  6972. * distributed under the License is distributed on an "AS IS" BASIS,
  6973. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6974. * See the License for the specific language governing permissions and
  6975. * limitations under the License.
  6976. */
  6977. function _isWorker() {
  6978. return (typeof _window()['WorkerGlobalScope'] !== 'undefined' &&
  6979. typeof _window()['importScripts'] === 'function');
  6980. }
  6981. async function _getActiveServiceWorker() {
  6982. if (!(navigator === null || navigator === void 0 ? void 0 : navigator.serviceWorker)) {
  6983. return null;
  6984. }
  6985. try {
  6986. const registration = await navigator.serviceWorker.ready;
  6987. return registration.active;
  6988. }
  6989. catch (_a) {
  6990. return null;
  6991. }
  6992. }
  6993. function _getServiceWorkerController() {
  6994. var _a;
  6995. return ((_a = navigator === null || navigator === void 0 ? void 0 : navigator.serviceWorker) === null || _a === void 0 ? void 0 : _a.controller) || null;
  6996. }
  6997. function _getWorkerGlobalScope() {
  6998. return _isWorker() ? self : null;
  6999. }
  7000. /**
  7001. * @license
  7002. * Copyright 2019 Google LLC
  7003. *
  7004. * Licensed under the Apache License, Version 2.0 (the "License");
  7005. * you may not use this file except in compliance with the License.
  7006. * You may obtain a copy of the License at
  7007. *
  7008. * http://www.apache.org/licenses/LICENSE-2.0
  7009. *
  7010. * Unless required by applicable law or agreed to in writing, software
  7011. * distributed under the License is distributed on an "AS IS" BASIS,
  7012. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7013. * See the License for the specific language governing permissions and
  7014. * limitations under the License.
  7015. */
  7016. const DB_NAME = 'firebaseLocalStorageDb';
  7017. const DB_VERSION = 1;
  7018. const DB_OBJECTSTORE_NAME = 'firebaseLocalStorage';
  7019. const DB_DATA_KEYPATH = 'fbase_key';
  7020. /**
  7021. * Promise wrapper for IDBRequest
  7022. *
  7023. * Unfortunately we can't cleanly extend Promise<T> since promises are not callable in ES6
  7024. *
  7025. */
  7026. class DBPromise {
  7027. constructor(request) {
  7028. this.request = request;
  7029. }
  7030. toPromise() {
  7031. return new Promise((resolve, reject) => {
  7032. this.request.addEventListener('success', () => {
  7033. resolve(this.request.result);
  7034. });
  7035. this.request.addEventListener('error', () => {
  7036. reject(this.request.error);
  7037. });
  7038. });
  7039. }
  7040. }
  7041. function getObjectStore(db, isReadWrite) {
  7042. return db
  7043. .transaction([DB_OBJECTSTORE_NAME], isReadWrite ? 'readwrite' : 'readonly')
  7044. .objectStore(DB_OBJECTSTORE_NAME);
  7045. }
  7046. function _deleteDatabase() {
  7047. const request = indexedDB.deleteDatabase(DB_NAME);
  7048. return new DBPromise(request).toPromise();
  7049. }
  7050. function _openDatabase() {
  7051. const request = indexedDB.open(DB_NAME, DB_VERSION);
  7052. return new Promise((resolve, reject) => {
  7053. request.addEventListener('error', () => {
  7054. reject(request.error);
  7055. });
  7056. request.addEventListener('upgradeneeded', () => {
  7057. const db = request.result;
  7058. try {
  7059. db.createObjectStore(DB_OBJECTSTORE_NAME, { keyPath: DB_DATA_KEYPATH });
  7060. }
  7061. catch (e) {
  7062. reject(e);
  7063. }
  7064. });
  7065. request.addEventListener('success', async () => {
  7066. const db = request.result;
  7067. // Strange bug that occurs in Firefox when multiple tabs are opened at the
  7068. // same time. The only way to recover seems to be deleting the database
  7069. // and re-initializing it.
  7070. // https://github.com/firebase/firebase-js-sdk/issues/634
  7071. if (!db.objectStoreNames.contains(DB_OBJECTSTORE_NAME)) {
  7072. // Need to close the database or else you get a `blocked` event
  7073. db.close();
  7074. await _deleteDatabase();
  7075. resolve(await _openDatabase());
  7076. }
  7077. else {
  7078. resolve(db);
  7079. }
  7080. });
  7081. });
  7082. }
  7083. async function _putObject(db, key, value) {
  7084. const request = getObjectStore(db, true).put({
  7085. [DB_DATA_KEYPATH]: key,
  7086. value
  7087. });
  7088. return new DBPromise(request).toPromise();
  7089. }
  7090. async function getObject(db, key) {
  7091. const request = getObjectStore(db, false).get(key);
  7092. const data = await new DBPromise(request).toPromise();
  7093. return data === undefined ? null : data.value;
  7094. }
  7095. function _deleteObject(db, key) {
  7096. const request = getObjectStore(db, true).delete(key);
  7097. return new DBPromise(request).toPromise();
  7098. }
  7099. const _POLLING_INTERVAL_MS = 800;
  7100. const _TRANSACTION_RETRY_COUNT = 3;
  7101. class IndexedDBLocalPersistence {
  7102. constructor() {
  7103. this.type = "LOCAL" /* PersistenceType.LOCAL */;
  7104. this._shouldAllowMigration = true;
  7105. this.listeners = {};
  7106. this.localCache = {};
  7107. // setTimeout return value is platform specific
  7108. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  7109. this.pollTimer = null;
  7110. this.pendingWrites = 0;
  7111. this.receiver = null;
  7112. this.sender = null;
  7113. this.serviceWorkerReceiverAvailable = false;
  7114. this.activeServiceWorker = null;
  7115. // Fire & forget the service worker registration as it may never resolve
  7116. this._workerInitializationPromise =
  7117. this.initializeServiceWorkerMessaging().then(() => { }, () => { });
  7118. }
  7119. async _openDb() {
  7120. if (this.db) {
  7121. return this.db;
  7122. }
  7123. this.db = await _openDatabase();
  7124. return this.db;
  7125. }
  7126. async _withRetries(op) {
  7127. let numAttempts = 0;
  7128. while (true) {
  7129. try {
  7130. const db = await this._openDb();
  7131. return await op(db);
  7132. }
  7133. catch (e) {
  7134. if (numAttempts++ > _TRANSACTION_RETRY_COUNT) {
  7135. throw e;
  7136. }
  7137. if (this.db) {
  7138. this.db.close();
  7139. this.db = undefined;
  7140. }
  7141. // TODO: consider adding exponential backoff
  7142. }
  7143. }
  7144. }
  7145. /**
  7146. * IndexedDB events do not propagate from the main window to the worker context. We rely on a
  7147. * postMessage interface to send these events to the worker ourselves.
  7148. */
  7149. async initializeServiceWorkerMessaging() {
  7150. return _isWorker() ? this.initializeReceiver() : this.initializeSender();
  7151. }
  7152. /**
  7153. * As the worker we should listen to events from the main window.
  7154. */
  7155. async initializeReceiver() {
  7156. this.receiver = Receiver._getInstance(_getWorkerGlobalScope());
  7157. // Refresh from persistence if we receive a KeyChanged message.
  7158. this.receiver._subscribe("keyChanged" /* _EventType.KEY_CHANGED */, async (_origin, data) => {
  7159. const keys = await this._poll();
  7160. return {
  7161. keyProcessed: keys.includes(data.key)
  7162. };
  7163. });
  7164. // Let the sender know that we are listening so they give us more timeout.
  7165. this.receiver._subscribe("ping" /* _EventType.PING */, async (_origin, _data) => {
  7166. return ["keyChanged" /* _EventType.KEY_CHANGED */];
  7167. });
  7168. }
  7169. /**
  7170. * As the main window, we should let the worker know when keys change (set and remove).
  7171. *
  7172. * @remarks
  7173. * {@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/ready | ServiceWorkerContainer.ready}
  7174. * may not resolve.
  7175. */
  7176. async initializeSender() {
  7177. var _a, _b;
  7178. // Check to see if there's an active service worker.
  7179. this.activeServiceWorker = await _getActiveServiceWorker();
  7180. if (!this.activeServiceWorker) {
  7181. return;
  7182. }
  7183. this.sender = new Sender(this.activeServiceWorker);
  7184. // Ping the service worker to check what events they can handle.
  7185. const results = await this.sender._send("ping" /* _EventType.PING */, {}, 800 /* _TimeoutDuration.LONG_ACK */);
  7186. if (!results) {
  7187. return;
  7188. }
  7189. if (((_a = results[0]) === null || _a === void 0 ? void 0 : _a.fulfilled) &&
  7190. ((_b = results[0]) === null || _b === void 0 ? void 0 : _b.value.includes("keyChanged" /* _EventType.KEY_CHANGED */))) {
  7191. this.serviceWorkerReceiverAvailable = true;
  7192. }
  7193. }
  7194. /**
  7195. * Let the worker know about a changed key, the exact key doesn't technically matter since the
  7196. * worker will just trigger a full sync anyway.
  7197. *
  7198. * @remarks
  7199. * For now, we only support one service worker per page.
  7200. *
  7201. * @param key - Storage key which changed.
  7202. */
  7203. async notifyServiceWorker(key) {
  7204. if (!this.sender ||
  7205. !this.activeServiceWorker ||
  7206. _getServiceWorkerController() !== this.activeServiceWorker) {
  7207. return;
  7208. }
  7209. try {
  7210. await this.sender._send("keyChanged" /* _EventType.KEY_CHANGED */, { key },
  7211. // Use long timeout if receiver has previously responded to a ping from us.
  7212. this.serviceWorkerReceiverAvailable
  7213. ? 800 /* _TimeoutDuration.LONG_ACK */
  7214. : 50 /* _TimeoutDuration.ACK */);
  7215. }
  7216. catch (_a) {
  7217. // This is a best effort approach. Ignore errors.
  7218. }
  7219. }
  7220. async _isAvailable() {
  7221. try {
  7222. if (!indexedDB) {
  7223. return false;
  7224. }
  7225. const db = await _openDatabase();
  7226. await _putObject(db, STORAGE_AVAILABLE_KEY, '1');
  7227. await _deleteObject(db, STORAGE_AVAILABLE_KEY);
  7228. return true;
  7229. }
  7230. catch (_a) { }
  7231. return false;
  7232. }
  7233. async _withPendingWrite(write) {
  7234. this.pendingWrites++;
  7235. try {
  7236. await write();
  7237. }
  7238. finally {
  7239. this.pendingWrites--;
  7240. }
  7241. }
  7242. async _set(key, value) {
  7243. return this._withPendingWrite(async () => {
  7244. await this._withRetries((db) => _putObject(db, key, value));
  7245. this.localCache[key] = value;
  7246. return this.notifyServiceWorker(key);
  7247. });
  7248. }
  7249. async _get(key) {
  7250. const obj = (await this._withRetries((db) => getObject(db, key)));
  7251. this.localCache[key] = obj;
  7252. return obj;
  7253. }
  7254. async _remove(key) {
  7255. return this._withPendingWrite(async () => {
  7256. await this._withRetries((db) => _deleteObject(db, key));
  7257. delete this.localCache[key];
  7258. return this.notifyServiceWorker(key);
  7259. });
  7260. }
  7261. async _poll() {
  7262. // TODO: check if we need to fallback if getAll is not supported
  7263. const result = await this._withRetries((db) => {
  7264. const getAllRequest = getObjectStore(db, false).getAll();
  7265. return new DBPromise(getAllRequest).toPromise();
  7266. });
  7267. if (!result) {
  7268. return [];
  7269. }
  7270. // If we have pending writes in progress abort, we'll get picked up on the next poll
  7271. if (this.pendingWrites !== 0) {
  7272. return [];
  7273. }
  7274. const keys = [];
  7275. const keysInResult = new Set();
  7276. for (const { fbase_key: key, value } of result) {
  7277. keysInResult.add(key);
  7278. if (JSON.stringify(this.localCache[key]) !== JSON.stringify(value)) {
  7279. this.notifyListeners(key, value);
  7280. keys.push(key);
  7281. }
  7282. }
  7283. for (const localKey of Object.keys(this.localCache)) {
  7284. if (this.localCache[localKey] && !keysInResult.has(localKey)) {
  7285. // Deleted
  7286. this.notifyListeners(localKey, null);
  7287. keys.push(localKey);
  7288. }
  7289. }
  7290. return keys;
  7291. }
  7292. notifyListeners(key, newValue) {
  7293. this.localCache[key] = newValue;
  7294. const listeners = this.listeners[key];
  7295. if (listeners) {
  7296. for (const listener of Array.from(listeners)) {
  7297. listener(newValue);
  7298. }
  7299. }
  7300. }
  7301. startPolling() {
  7302. this.stopPolling();
  7303. this.pollTimer = setInterval(async () => this._poll(), _POLLING_INTERVAL_MS);
  7304. }
  7305. stopPolling() {
  7306. if (this.pollTimer) {
  7307. clearInterval(this.pollTimer);
  7308. this.pollTimer = null;
  7309. }
  7310. }
  7311. _addListener(key, listener) {
  7312. if (Object.keys(this.listeners).length === 0) {
  7313. this.startPolling();
  7314. }
  7315. if (!this.listeners[key]) {
  7316. this.listeners[key] = new Set();
  7317. // Populate the cache to avoid spuriously triggering on first poll.
  7318. void this._get(key); // This can happen in the background async and we can return immediately.
  7319. }
  7320. this.listeners[key].add(listener);
  7321. }
  7322. _removeListener(key, listener) {
  7323. if (this.listeners[key]) {
  7324. this.listeners[key].delete(listener);
  7325. if (this.listeners[key].size === 0) {
  7326. delete this.listeners[key];
  7327. }
  7328. }
  7329. if (Object.keys(this.listeners).length === 0) {
  7330. this.stopPolling();
  7331. }
  7332. }
  7333. }
  7334. IndexedDBLocalPersistence.type = 'LOCAL';
  7335. /**
  7336. * An implementation of {@link Persistence} of type `LOCAL` using `indexedDB`
  7337. * for the underlying storage.
  7338. *
  7339. * @public
  7340. */
  7341. const indexedDBLocalPersistence = IndexedDBLocalPersistence;
  7342. /**
  7343. * @license
  7344. * Copyright 2020 Google LLC
  7345. *
  7346. * Licensed under the Apache License, Version 2.0 (the "License");
  7347. * you may not use this file except in compliance with the License.
  7348. * You may obtain a copy of the License at
  7349. *
  7350. * http://www.apache.org/licenses/LICENSE-2.0
  7351. *
  7352. * Unless required by applicable law or agreed to in writing, software
  7353. * distributed under the License is distributed on an "AS IS" BASIS,
  7354. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7355. * See the License for the specific language governing permissions and
  7356. * limitations under the License.
  7357. */
  7358. function startSignInPhoneMfa(auth, request) {
  7359. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v2/accounts/mfaSignIn:start" /* Endpoint.START_MFA_SIGN_IN */, _addTidIfNecessary(auth, request));
  7360. }
  7361. function finalizeSignInPhoneMfa(auth, request) {
  7362. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v2/accounts/mfaSignIn:finalize" /* Endpoint.FINALIZE_MFA_SIGN_IN */, _addTidIfNecessary(auth, request));
  7363. }
  7364. function finalizeSignInTotpMfa(auth, request) {
  7365. return _performApiRequest(auth, "POST" /* HttpMethod.POST */, "/v2/accounts/mfaSignIn:finalize" /* Endpoint.FINALIZE_MFA_SIGN_IN */, _addTidIfNecessary(auth, request));
  7366. }
  7367. /**
  7368. * @license
  7369. * Copyright 2020 Google LLC
  7370. *
  7371. * Licensed under the Apache License, Version 2.0 (the "License");
  7372. * you may not use this file except in compliance with the License.
  7373. * You may obtain a copy of the License at
  7374. *
  7375. * http://www.apache.org/licenses/LICENSE-2.0
  7376. *
  7377. * Unless required by applicable law or agreed to in writing, software
  7378. * distributed under the License is distributed on an "AS IS" BASIS,
  7379. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7380. * See the License for the specific language governing permissions and
  7381. * limitations under the License.
  7382. */
  7383. const _SOLVE_TIME_MS = 500;
  7384. const _EXPIRATION_TIME_MS = 60000;
  7385. const _WIDGET_ID_START = 1000000000000;
  7386. class MockReCaptcha {
  7387. constructor(auth) {
  7388. this.auth = auth;
  7389. this.counter = _WIDGET_ID_START;
  7390. this._widgets = new Map();
  7391. }
  7392. render(container, parameters) {
  7393. const id = this.counter;
  7394. this._widgets.set(id, new MockWidget(container, this.auth.name, parameters || {}));
  7395. this.counter++;
  7396. return id;
  7397. }
  7398. reset(optWidgetId) {
  7399. var _a;
  7400. const id = optWidgetId || _WIDGET_ID_START;
  7401. void ((_a = this._widgets.get(id)) === null || _a === void 0 ? void 0 : _a.delete());
  7402. this._widgets.delete(id);
  7403. }
  7404. getResponse(optWidgetId) {
  7405. var _a;
  7406. const id = optWidgetId || _WIDGET_ID_START;
  7407. return ((_a = this._widgets.get(id)) === null || _a === void 0 ? void 0 : _a.getResponse()) || '';
  7408. }
  7409. async execute(optWidgetId) {
  7410. var _a;
  7411. const id = optWidgetId || _WIDGET_ID_START;
  7412. void ((_a = this._widgets.get(id)) === null || _a === void 0 ? void 0 : _a.execute());
  7413. return '';
  7414. }
  7415. }
  7416. class MockWidget {
  7417. constructor(containerOrId, appName, params) {
  7418. this.params = params;
  7419. this.timerId = null;
  7420. this.deleted = false;
  7421. this.responseToken = null;
  7422. this.clickHandler = () => {
  7423. this.execute();
  7424. };
  7425. const container = typeof containerOrId === 'string'
  7426. ? document.getElementById(containerOrId)
  7427. : containerOrId;
  7428. _assert(container, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */, { appName });
  7429. this.container = container;
  7430. this.isVisible = this.params.size !== 'invisible';
  7431. if (this.isVisible) {
  7432. this.execute();
  7433. }
  7434. else {
  7435. this.container.addEventListener('click', this.clickHandler);
  7436. }
  7437. }
  7438. getResponse() {
  7439. this.checkIfDeleted();
  7440. return this.responseToken;
  7441. }
  7442. delete() {
  7443. this.checkIfDeleted();
  7444. this.deleted = true;
  7445. if (this.timerId) {
  7446. clearTimeout(this.timerId);
  7447. this.timerId = null;
  7448. }
  7449. this.container.removeEventListener('click', this.clickHandler);
  7450. }
  7451. execute() {
  7452. this.checkIfDeleted();
  7453. if (this.timerId) {
  7454. return;
  7455. }
  7456. this.timerId = window.setTimeout(() => {
  7457. this.responseToken = generateRandomAlphaNumericString(50);
  7458. const { callback, 'expired-callback': expiredCallback } = this.params;
  7459. if (callback) {
  7460. try {
  7461. callback(this.responseToken);
  7462. }
  7463. catch (e) { }
  7464. }
  7465. this.timerId = window.setTimeout(() => {
  7466. this.timerId = null;
  7467. this.responseToken = null;
  7468. if (expiredCallback) {
  7469. try {
  7470. expiredCallback();
  7471. }
  7472. catch (e) { }
  7473. }
  7474. if (this.isVisible) {
  7475. this.execute();
  7476. }
  7477. }, _EXPIRATION_TIME_MS);
  7478. }, _SOLVE_TIME_MS);
  7479. }
  7480. checkIfDeleted() {
  7481. if (this.deleted) {
  7482. throw new Error('reCAPTCHA mock was already deleted!');
  7483. }
  7484. }
  7485. }
  7486. function generateRandomAlphaNumericString(len) {
  7487. const chars = [];
  7488. const allowedChars = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  7489. for (let i = 0; i < len; i++) {
  7490. chars.push(allowedChars.charAt(Math.floor(Math.random() * allowedChars.length)));
  7491. }
  7492. return chars.join('');
  7493. }
  7494. /**
  7495. * @license
  7496. * Copyright 2020 Google LLC
  7497. *
  7498. * Licensed under the Apache License, Version 2.0 (the "License");
  7499. * you may not use this file except in compliance with the License.
  7500. * You may obtain a copy of the License at
  7501. *
  7502. * http://www.apache.org/licenses/LICENSE-2.0
  7503. *
  7504. * Unless required by applicable law or agreed to in writing, software
  7505. * distributed under the License is distributed on an "AS IS" BASIS,
  7506. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7507. * See the License for the specific language governing permissions and
  7508. * limitations under the License.
  7509. */
  7510. // ReCaptcha will load using the same callback, so the callback function needs
  7511. // to be kept around
  7512. const _JSLOAD_CALLBACK = _generateCallbackName('rcb');
  7513. const NETWORK_TIMEOUT_DELAY = new Delay(30000, 60000);
  7514. const RECAPTCHA_BASE = 'https://www.google.com/recaptcha/api.js?';
  7515. /**
  7516. * Loader for the GReCaptcha library. There should only ever be one of this.
  7517. */
  7518. class ReCaptchaLoaderImpl {
  7519. constructor() {
  7520. var _a;
  7521. this.hostLanguage = '';
  7522. this.counter = 0;
  7523. /**
  7524. * Check for `render()` method. `window.grecaptcha` will exist if the Enterprise
  7525. * version of the ReCAPTCHA script was loaded by someone else (e.g. App Check) but
  7526. * `window.grecaptcha.render()` will not. Another load will add it.
  7527. */
  7528. this.librarySeparatelyLoaded = !!((_a = _window().grecaptcha) === null || _a === void 0 ? void 0 : _a.render);
  7529. }
  7530. load(auth, hl = '') {
  7531. _assert(isHostLanguageValid(hl), auth, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  7532. if (this.shouldResolveImmediately(hl) && isV2(_window().grecaptcha)) {
  7533. return Promise.resolve(_window().grecaptcha);
  7534. }
  7535. return new Promise((resolve, reject) => {
  7536. const networkTimeout = _window().setTimeout(() => {
  7537. reject(_createError(auth, "network-request-failed" /* AuthErrorCode.NETWORK_REQUEST_FAILED */));
  7538. }, NETWORK_TIMEOUT_DELAY.get());
  7539. _window()[_JSLOAD_CALLBACK] = () => {
  7540. _window().clearTimeout(networkTimeout);
  7541. delete _window()[_JSLOAD_CALLBACK];
  7542. const recaptcha = _window().grecaptcha;
  7543. if (!recaptcha || !isV2(recaptcha)) {
  7544. reject(_createError(auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */));
  7545. return;
  7546. }
  7547. // Wrap the greptcha render function so that we know if the developer has
  7548. // called it separately
  7549. const render = recaptcha.render;
  7550. recaptcha.render = (container, params) => {
  7551. const widgetId = render(container, params);
  7552. this.counter++;
  7553. return widgetId;
  7554. };
  7555. this.hostLanguage = hl;
  7556. resolve(recaptcha);
  7557. };
  7558. const url = `${RECAPTCHA_BASE}?${util.querystring({
  7559. onload: _JSLOAD_CALLBACK,
  7560. render: 'explicit',
  7561. hl
  7562. })}`;
  7563. _loadJS(url).catch(() => {
  7564. clearTimeout(networkTimeout);
  7565. reject(_createError(auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */));
  7566. });
  7567. });
  7568. }
  7569. clearedOneInstance() {
  7570. this.counter--;
  7571. }
  7572. shouldResolveImmediately(hl) {
  7573. var _a;
  7574. // We can resolve immediately if:
  7575. // • grecaptcha is already defined AND (
  7576. // 1. the requested language codes are the same OR
  7577. // 2. there exists already a ReCaptcha on the page
  7578. // 3. the library was already loaded by the app
  7579. // In cases (2) and (3), we _can't_ reload as it would break the recaptchas
  7580. // that are already in the page
  7581. return (!!((_a = _window().grecaptcha) === null || _a === void 0 ? void 0 : _a.render) &&
  7582. (hl === this.hostLanguage ||
  7583. this.counter > 0 ||
  7584. this.librarySeparatelyLoaded));
  7585. }
  7586. }
  7587. function isHostLanguageValid(hl) {
  7588. return hl.length <= 6 && /^\s*[a-zA-Z0-9\-]*\s*$/.test(hl);
  7589. }
  7590. class MockReCaptchaLoaderImpl {
  7591. async load(auth) {
  7592. return new MockReCaptcha(auth);
  7593. }
  7594. clearedOneInstance() { }
  7595. }
  7596. /**
  7597. * @license
  7598. * Copyright 2020 Google LLC
  7599. *
  7600. * Licensed under the Apache License, Version 2.0 (the "License");
  7601. * you may not use this file except in compliance with the License.
  7602. * You may obtain a copy of the License at
  7603. *
  7604. * http://www.apache.org/licenses/LICENSE-2.0
  7605. *
  7606. * Unless required by applicable law or agreed to in writing, software
  7607. * distributed under the License is distributed on an "AS IS" BASIS,
  7608. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7609. * See the License for the specific language governing permissions and
  7610. * limitations under the License.
  7611. */
  7612. const RECAPTCHA_VERIFIER_TYPE = 'recaptcha';
  7613. const DEFAULT_PARAMS = {
  7614. theme: 'light',
  7615. type: 'image'
  7616. };
  7617. /**
  7618. * An {@link https://www.google.com/recaptcha/ | reCAPTCHA}-based application verifier.
  7619. *
  7620. * @public
  7621. */
  7622. class RecaptchaVerifier {
  7623. /**
  7624. *
  7625. * @param containerOrId - The reCAPTCHA container parameter.
  7626. *
  7627. * @remarks
  7628. * This has different meaning depending on whether the reCAPTCHA is hidden or visible. For a
  7629. * visible reCAPTCHA the container must be empty. If a string is used, it has to correspond to
  7630. * an element ID. The corresponding element must also must be in the DOM at the time of
  7631. * initialization.
  7632. *
  7633. * @param parameters - The optional reCAPTCHA parameters.
  7634. *
  7635. * @remarks
  7636. * Check the reCAPTCHA docs for a comprehensive list. All parameters are accepted except for
  7637. * the sitekey. Firebase Auth backend provisions a reCAPTCHA for each project and will
  7638. * configure this upon rendering. For an invisible reCAPTCHA, a size key must have the value
  7639. * 'invisible'.
  7640. *
  7641. * @param authExtern - The corresponding Firebase {@link Auth} instance.
  7642. */
  7643. constructor(containerOrId, parameters = Object.assign({}, DEFAULT_PARAMS), authExtern) {
  7644. this.parameters = parameters;
  7645. /**
  7646. * The application verifier type.
  7647. *
  7648. * @remarks
  7649. * For a reCAPTCHA verifier, this is 'recaptcha'.
  7650. */
  7651. this.type = RECAPTCHA_VERIFIER_TYPE;
  7652. this.destroyed = false;
  7653. this.widgetId = null;
  7654. this.tokenChangeListeners = new Set();
  7655. this.renderPromise = null;
  7656. this.recaptcha = null;
  7657. this.auth = _castAuth(authExtern);
  7658. this.isInvisible = this.parameters.size === 'invisible';
  7659. _assert(typeof document !== 'undefined', this.auth, "operation-not-supported-in-this-environment" /* AuthErrorCode.OPERATION_NOT_SUPPORTED */);
  7660. const container = typeof containerOrId === 'string'
  7661. ? document.getElementById(containerOrId)
  7662. : containerOrId;
  7663. _assert(container, this.auth, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  7664. this.container = container;
  7665. this.parameters.callback = this.makeTokenCallback(this.parameters.callback);
  7666. this._recaptchaLoader = this.auth.settings.appVerificationDisabledForTesting
  7667. ? new MockReCaptchaLoaderImpl()
  7668. : new ReCaptchaLoaderImpl();
  7669. this.validateStartingState();
  7670. // TODO: Figure out if sdk version is needed
  7671. }
  7672. /**
  7673. * Waits for the user to solve the reCAPTCHA and resolves with the reCAPTCHA token.
  7674. *
  7675. * @returns A Promise for the reCAPTCHA token.
  7676. */
  7677. async verify() {
  7678. this.assertNotDestroyed();
  7679. const id = await this.render();
  7680. const recaptcha = this.getAssertedRecaptcha();
  7681. const response = recaptcha.getResponse(id);
  7682. if (response) {
  7683. return response;
  7684. }
  7685. return new Promise(resolve => {
  7686. const tokenChange = (token) => {
  7687. if (!token) {
  7688. return; // Ignore token expirations.
  7689. }
  7690. this.tokenChangeListeners.delete(tokenChange);
  7691. resolve(token);
  7692. };
  7693. this.tokenChangeListeners.add(tokenChange);
  7694. if (this.isInvisible) {
  7695. recaptcha.execute(id);
  7696. }
  7697. });
  7698. }
  7699. /**
  7700. * Renders the reCAPTCHA widget on the page.
  7701. *
  7702. * @returns A Promise that resolves with the reCAPTCHA widget ID.
  7703. */
  7704. render() {
  7705. try {
  7706. this.assertNotDestroyed();
  7707. }
  7708. catch (e) {
  7709. // This method returns a promise. Since it's not async (we want to return the
  7710. // _same_ promise if rendering is still occurring), the API surface should
  7711. // reject with the error rather than just throw
  7712. return Promise.reject(e);
  7713. }
  7714. if (this.renderPromise) {
  7715. return this.renderPromise;
  7716. }
  7717. this.renderPromise = this.makeRenderPromise().catch(e => {
  7718. this.renderPromise = null;
  7719. throw e;
  7720. });
  7721. return this.renderPromise;
  7722. }
  7723. /** @internal */
  7724. _reset() {
  7725. this.assertNotDestroyed();
  7726. if (this.widgetId !== null) {
  7727. this.getAssertedRecaptcha().reset(this.widgetId);
  7728. }
  7729. }
  7730. /**
  7731. * Clears the reCAPTCHA widget from the page and destroys the instance.
  7732. */
  7733. clear() {
  7734. this.assertNotDestroyed();
  7735. this.destroyed = true;
  7736. this._recaptchaLoader.clearedOneInstance();
  7737. if (!this.isInvisible) {
  7738. this.container.childNodes.forEach(node => {
  7739. this.container.removeChild(node);
  7740. });
  7741. }
  7742. }
  7743. validateStartingState() {
  7744. _assert(!this.parameters.sitekey, this.auth, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  7745. _assert(this.isInvisible || !this.container.hasChildNodes(), this.auth, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  7746. _assert(typeof document !== 'undefined', this.auth, "operation-not-supported-in-this-environment" /* AuthErrorCode.OPERATION_NOT_SUPPORTED */);
  7747. }
  7748. makeTokenCallback(existing) {
  7749. return token => {
  7750. this.tokenChangeListeners.forEach(listener => listener(token));
  7751. if (typeof existing === 'function') {
  7752. existing(token);
  7753. }
  7754. else if (typeof existing === 'string') {
  7755. const globalFunc = _window()[existing];
  7756. if (typeof globalFunc === 'function') {
  7757. globalFunc(token);
  7758. }
  7759. }
  7760. };
  7761. }
  7762. assertNotDestroyed() {
  7763. _assert(!this.destroyed, this.auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  7764. }
  7765. async makeRenderPromise() {
  7766. await this.init();
  7767. if (!this.widgetId) {
  7768. let container = this.container;
  7769. if (!this.isInvisible) {
  7770. const guaranteedEmpty = document.createElement('div');
  7771. container.appendChild(guaranteedEmpty);
  7772. container = guaranteedEmpty;
  7773. }
  7774. this.widgetId = this.getAssertedRecaptcha().render(container, this.parameters);
  7775. }
  7776. return this.widgetId;
  7777. }
  7778. async init() {
  7779. _assert(_isHttpOrHttps() && !_isWorker(), this.auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  7780. await domReady();
  7781. this.recaptcha = await this._recaptchaLoader.load(this.auth, this.auth.languageCode || undefined);
  7782. const siteKey = await getRecaptchaParams(this.auth);
  7783. _assert(siteKey, this.auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  7784. this.parameters.sitekey = siteKey;
  7785. }
  7786. getAssertedRecaptcha() {
  7787. _assert(this.recaptcha, this.auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  7788. return this.recaptcha;
  7789. }
  7790. }
  7791. function domReady() {
  7792. let resolver = null;
  7793. return new Promise(resolve => {
  7794. if (document.readyState === 'complete') {
  7795. resolve();
  7796. return;
  7797. }
  7798. // Document not ready, wait for load before resolving.
  7799. // Save resolver, so we can remove listener in case it was externally
  7800. // cancelled.
  7801. resolver = () => resolve();
  7802. window.addEventListener('load', resolver);
  7803. }).catch(e => {
  7804. if (resolver) {
  7805. window.removeEventListener('load', resolver);
  7806. }
  7807. throw e;
  7808. });
  7809. }
  7810. /**
  7811. * @license
  7812. * Copyright 2020 Google LLC
  7813. *
  7814. * Licensed under the Apache License, Version 2.0 (the "License");
  7815. * you may not use this file except in compliance with the License.
  7816. * You may obtain a copy of the License at
  7817. *
  7818. * http://www.apache.org/licenses/LICENSE-2.0
  7819. *
  7820. * Unless required by applicable law or agreed to in writing, software
  7821. * distributed under the License is distributed on an "AS IS" BASIS,
  7822. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7823. * See the License for the specific language governing permissions and
  7824. * limitations under the License.
  7825. */
  7826. class ConfirmationResultImpl {
  7827. constructor(verificationId, onConfirmation) {
  7828. this.verificationId = verificationId;
  7829. this.onConfirmation = onConfirmation;
  7830. }
  7831. confirm(verificationCode) {
  7832. const authCredential = PhoneAuthCredential._fromVerification(this.verificationId, verificationCode);
  7833. return this.onConfirmation(authCredential);
  7834. }
  7835. }
  7836. /**
  7837. * Asynchronously signs in using a phone number.
  7838. *
  7839. * @remarks
  7840. * This method sends a code via SMS to the given
  7841. * phone number, and returns a {@link ConfirmationResult}. After the user
  7842. * provides the code sent to their phone, call {@link ConfirmationResult.confirm}
  7843. * with the code to sign the user in.
  7844. *
  7845. * For abuse prevention, this method also requires a {@link ApplicationVerifier}.
  7846. * This SDK includes a reCAPTCHA-based implementation, {@link RecaptchaVerifier}.
  7847. * This function can work on other platforms that do not support the
  7848. * {@link RecaptchaVerifier} (like React Native), but you need to use a
  7849. * third-party {@link ApplicationVerifier} implementation.
  7850. *
  7851. * @example
  7852. * ```javascript
  7853. * // 'recaptcha-container' is the ID of an element in the DOM.
  7854. * const applicationVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
  7855. * const confirmationResult = await signInWithPhoneNumber(auth, phoneNumber, applicationVerifier);
  7856. * // Obtain a verificationCode from the user.
  7857. * const credential = await confirmationResult.confirm(verificationCode);
  7858. * ```
  7859. *
  7860. * @param auth - The {@link Auth} instance.
  7861. * @param phoneNumber - The user's phone number in E.164 format (e.g. +16505550101).
  7862. * @param appVerifier - The {@link ApplicationVerifier}.
  7863. *
  7864. * @public
  7865. */
  7866. async function signInWithPhoneNumber(auth, phoneNumber, appVerifier) {
  7867. const authInternal = _castAuth(auth);
  7868. const verificationId = await _verifyPhoneNumber(authInternal, phoneNumber, util.getModularInstance(appVerifier));
  7869. return new ConfirmationResultImpl(verificationId, cred => signInWithCredential(authInternal, cred));
  7870. }
  7871. /**
  7872. * Links the user account with the given phone number.
  7873. *
  7874. * @param user - The user.
  7875. * @param phoneNumber - The user's phone number in E.164 format (e.g. +16505550101).
  7876. * @param appVerifier - The {@link ApplicationVerifier}.
  7877. *
  7878. * @public
  7879. */
  7880. async function linkWithPhoneNumber(user, phoneNumber, appVerifier) {
  7881. const userInternal = util.getModularInstance(user);
  7882. await _assertLinkedStatus(false, userInternal, "phone" /* ProviderId.PHONE */);
  7883. const verificationId = await _verifyPhoneNumber(userInternal.auth, phoneNumber, util.getModularInstance(appVerifier));
  7884. return new ConfirmationResultImpl(verificationId, cred => linkWithCredential(userInternal, cred));
  7885. }
  7886. /**
  7887. * Re-authenticates a user using a fresh phone credential.
  7888. *
  7889. * @remarks Use before operations such as {@link updatePassword} that require tokens from recent sign-in attempts.
  7890. *
  7891. * @param user - The user.
  7892. * @param phoneNumber - The user's phone number in E.164 format (e.g. +16505550101).
  7893. * @param appVerifier - The {@link ApplicationVerifier}.
  7894. *
  7895. * @public
  7896. */
  7897. async function reauthenticateWithPhoneNumber(user, phoneNumber, appVerifier) {
  7898. const userInternal = util.getModularInstance(user);
  7899. const verificationId = await _verifyPhoneNumber(userInternal.auth, phoneNumber, util.getModularInstance(appVerifier));
  7900. return new ConfirmationResultImpl(verificationId, cred => reauthenticateWithCredential(userInternal, cred));
  7901. }
  7902. /**
  7903. * Returns a verification ID to be used in conjunction with the SMS code that is sent.
  7904. *
  7905. */
  7906. async function _verifyPhoneNumber(auth, options, verifier) {
  7907. var _a;
  7908. const recaptchaToken = await verifier.verify();
  7909. try {
  7910. _assert(typeof recaptchaToken === 'string', auth, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  7911. _assert(verifier.type === RECAPTCHA_VERIFIER_TYPE, auth, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  7912. let phoneInfoOptions;
  7913. if (typeof options === 'string') {
  7914. phoneInfoOptions = {
  7915. phoneNumber: options
  7916. };
  7917. }
  7918. else {
  7919. phoneInfoOptions = options;
  7920. }
  7921. if ('session' in phoneInfoOptions) {
  7922. const session = phoneInfoOptions.session;
  7923. if ('phoneNumber' in phoneInfoOptions) {
  7924. _assert(session.type === "enroll" /* MultiFactorSessionType.ENROLL */, auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  7925. const response = await startEnrollPhoneMfa(auth, {
  7926. idToken: session.credential,
  7927. phoneEnrollmentInfo: {
  7928. phoneNumber: phoneInfoOptions.phoneNumber,
  7929. recaptchaToken
  7930. }
  7931. });
  7932. return response.phoneSessionInfo.sessionInfo;
  7933. }
  7934. else {
  7935. _assert(session.type === "signin" /* MultiFactorSessionType.SIGN_IN */, auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  7936. const mfaEnrollmentId = ((_a = phoneInfoOptions.multiFactorHint) === null || _a === void 0 ? void 0 : _a.uid) ||
  7937. phoneInfoOptions.multiFactorUid;
  7938. _assert(mfaEnrollmentId, auth, "missing-multi-factor-info" /* AuthErrorCode.MISSING_MFA_INFO */);
  7939. const response = await startSignInPhoneMfa(auth, {
  7940. mfaPendingCredential: session.credential,
  7941. mfaEnrollmentId,
  7942. phoneSignInInfo: {
  7943. recaptchaToken
  7944. }
  7945. });
  7946. return response.phoneResponseInfo.sessionInfo;
  7947. }
  7948. }
  7949. else {
  7950. const { sessionInfo } = await sendPhoneVerificationCode(auth, {
  7951. phoneNumber: phoneInfoOptions.phoneNumber,
  7952. recaptchaToken
  7953. });
  7954. return sessionInfo;
  7955. }
  7956. }
  7957. finally {
  7958. verifier._reset();
  7959. }
  7960. }
  7961. /**
  7962. * Updates the user's phone number.
  7963. *
  7964. * @example
  7965. * ```
  7966. * // 'recaptcha-container' is the ID of an element in the DOM.
  7967. * const applicationVerifier = new RecaptchaVerifier('recaptcha-container');
  7968. * const provider = new PhoneAuthProvider(auth);
  7969. * const verificationId = await provider.verifyPhoneNumber('+16505550101', applicationVerifier);
  7970. * // Obtain the verificationCode from the user.
  7971. * const phoneCredential = PhoneAuthProvider.credential(verificationId, verificationCode);
  7972. * await updatePhoneNumber(user, phoneCredential);
  7973. * ```
  7974. *
  7975. * @param user - The user.
  7976. * @param credential - A credential authenticating the new phone number.
  7977. *
  7978. * @public
  7979. */
  7980. async function updatePhoneNumber(user, credential) {
  7981. await _link$1(util.getModularInstance(user), credential);
  7982. }
  7983. /**
  7984. * @license
  7985. * Copyright 2020 Google LLC
  7986. *
  7987. * Licensed under the Apache License, Version 2.0 (the "License");
  7988. * you may not use this file except in compliance with the License.
  7989. * You may obtain a copy of the License at
  7990. *
  7991. * http://www.apache.org/licenses/LICENSE-2.0
  7992. *
  7993. * Unless required by applicable law or agreed to in writing, software
  7994. * distributed under the License is distributed on an "AS IS" BASIS,
  7995. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  7996. * See the License for the specific language governing permissions and
  7997. * limitations under the License.
  7998. */
  7999. /**
  8000. * Provider for generating an {@link PhoneAuthCredential}.
  8001. *
  8002. * @example
  8003. * ```javascript
  8004. * // 'recaptcha-container' is the ID of an element in the DOM.
  8005. * const applicationVerifier = new RecaptchaVerifier('recaptcha-container');
  8006. * const provider = new PhoneAuthProvider(auth);
  8007. * const verificationId = await provider.verifyPhoneNumber('+16505550101', applicationVerifier);
  8008. * // Obtain the verificationCode from the user.
  8009. * const phoneCredential = PhoneAuthProvider.credential(verificationId, verificationCode);
  8010. * const userCredential = await signInWithCredential(auth, phoneCredential);
  8011. * ```
  8012. *
  8013. * @public
  8014. */
  8015. class PhoneAuthProvider {
  8016. /**
  8017. * @param auth - The Firebase {@link Auth} instance in which sign-ins should occur.
  8018. *
  8019. */
  8020. constructor(auth) {
  8021. /** Always set to {@link ProviderId}.PHONE. */
  8022. this.providerId = PhoneAuthProvider.PROVIDER_ID;
  8023. this.auth = _castAuth(auth);
  8024. }
  8025. /**
  8026. *
  8027. * Starts a phone number authentication flow by sending a verification code to the given phone
  8028. * number.
  8029. *
  8030. * @example
  8031. * ```javascript
  8032. * const provider = new PhoneAuthProvider(auth);
  8033. * const verificationId = await provider.verifyPhoneNumber(phoneNumber, applicationVerifier);
  8034. * // Obtain verificationCode from the user.
  8035. * const authCredential = PhoneAuthProvider.credential(verificationId, verificationCode);
  8036. * const userCredential = await signInWithCredential(auth, authCredential);
  8037. * ```
  8038. *
  8039. * @example
  8040. * An alternative flow is provided using the `signInWithPhoneNumber` method.
  8041. * ```javascript
  8042. * const confirmationResult = signInWithPhoneNumber(auth, phoneNumber, applicationVerifier);
  8043. * // Obtain verificationCode from the user.
  8044. * const userCredential = confirmationResult.confirm(verificationCode);
  8045. * ```
  8046. *
  8047. * @param phoneInfoOptions - The user's {@link PhoneInfoOptions}. The phone number should be in
  8048. * E.164 format (e.g. +16505550101).
  8049. * @param applicationVerifier - For abuse prevention, this method also requires a
  8050. * {@link ApplicationVerifier}. This SDK includes a reCAPTCHA-based implementation,
  8051. * {@link RecaptchaVerifier}.
  8052. *
  8053. * @returns A Promise for a verification ID that can be passed to
  8054. * {@link PhoneAuthProvider.credential} to identify this flow..
  8055. */
  8056. verifyPhoneNumber(phoneOptions, applicationVerifier) {
  8057. return _verifyPhoneNumber(this.auth, phoneOptions, util.getModularInstance(applicationVerifier));
  8058. }
  8059. /**
  8060. * Creates a phone auth credential, given the verification ID from
  8061. * {@link PhoneAuthProvider.verifyPhoneNumber} and the code that was sent to the user's
  8062. * mobile device.
  8063. *
  8064. * @example
  8065. * ```javascript
  8066. * const provider = new PhoneAuthProvider(auth);
  8067. * const verificationId = provider.verifyPhoneNumber(phoneNumber, applicationVerifier);
  8068. * // Obtain verificationCode from the user.
  8069. * const authCredential = PhoneAuthProvider.credential(verificationId, verificationCode);
  8070. * const userCredential = signInWithCredential(auth, authCredential);
  8071. * ```
  8072. *
  8073. * @example
  8074. * An alternative flow is provided using the `signInWithPhoneNumber` method.
  8075. * ```javascript
  8076. * const confirmationResult = await signInWithPhoneNumber(auth, phoneNumber, applicationVerifier);
  8077. * // Obtain verificationCode from the user.
  8078. * const userCredential = await confirmationResult.confirm(verificationCode);
  8079. * ```
  8080. *
  8081. * @param verificationId - The verification ID returned from {@link PhoneAuthProvider.verifyPhoneNumber}.
  8082. * @param verificationCode - The verification code sent to the user's mobile device.
  8083. *
  8084. * @returns The auth provider credential.
  8085. */
  8086. static credential(verificationId, verificationCode) {
  8087. return PhoneAuthCredential._fromVerification(verificationId, verificationCode);
  8088. }
  8089. /**
  8090. * Generates an {@link AuthCredential} from a {@link UserCredential}.
  8091. * @param userCredential - The user credential.
  8092. */
  8093. static credentialFromResult(userCredential) {
  8094. const credential = userCredential;
  8095. return PhoneAuthProvider.credentialFromTaggedObject(credential);
  8096. }
  8097. /**
  8098. * Returns an {@link AuthCredential} when passed an error.
  8099. *
  8100. * @remarks
  8101. *
  8102. * This method works for errors like
  8103. * `auth/account-exists-with-different-credentials`. This is useful for
  8104. * recovering when attempting to set a user's phone number but the number
  8105. * in question is already tied to another account. For example, the following
  8106. * code tries to update the current user's phone number, and if that
  8107. * fails, links the user with the account associated with that number:
  8108. *
  8109. * ```js
  8110. * const provider = new PhoneAuthProvider(auth);
  8111. * const verificationId = await provider.verifyPhoneNumber(number, verifier);
  8112. * try {
  8113. * const code = ''; // Prompt the user for the verification code
  8114. * await updatePhoneNumber(
  8115. * auth.currentUser,
  8116. * PhoneAuthProvider.credential(verificationId, code));
  8117. * } catch (e) {
  8118. * if ((e as FirebaseError)?.code === 'auth/account-exists-with-different-credential') {
  8119. * const cred = PhoneAuthProvider.credentialFromError(e);
  8120. * await linkWithCredential(auth.currentUser, cred);
  8121. * }
  8122. * }
  8123. *
  8124. * // At this point, auth.currentUser.phoneNumber === number.
  8125. * ```
  8126. *
  8127. * @param error - The error to generate a credential from.
  8128. */
  8129. static credentialFromError(error) {
  8130. return PhoneAuthProvider.credentialFromTaggedObject((error.customData || {}));
  8131. }
  8132. static credentialFromTaggedObject({ _tokenResponse: tokenResponse }) {
  8133. if (!tokenResponse) {
  8134. return null;
  8135. }
  8136. const { phoneNumber, temporaryProof } = tokenResponse;
  8137. if (phoneNumber && temporaryProof) {
  8138. return PhoneAuthCredential._fromTokenResponse(phoneNumber, temporaryProof);
  8139. }
  8140. return null;
  8141. }
  8142. }
  8143. /** Always set to {@link ProviderId}.PHONE. */
  8144. PhoneAuthProvider.PROVIDER_ID = "phone" /* ProviderId.PHONE */;
  8145. /** Always set to {@link SignInMethod}.PHONE. */
  8146. PhoneAuthProvider.PHONE_SIGN_IN_METHOD = "phone" /* SignInMethod.PHONE */;
  8147. /**
  8148. * @license
  8149. * Copyright 2021 Google LLC
  8150. *
  8151. * Licensed under the Apache License, Version 2.0 (the "License");
  8152. * you may not use this file except in compliance with the License.
  8153. * You may obtain a copy of the License at
  8154. *
  8155. * http://www.apache.org/licenses/LICENSE-2.0
  8156. *
  8157. * Unless required by applicable law or agreed to in writing, software
  8158. * distributed under the License is distributed on an "AS IS" BASIS,
  8159. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8160. * See the License for the specific language governing permissions and
  8161. * limitations under the License.
  8162. */
  8163. /**
  8164. * Chooses a popup/redirect resolver to use. This prefers the override (which
  8165. * is directly passed in), and falls back to the property set on the auth
  8166. * object. If neither are available, this function errors w/ an argument error.
  8167. */
  8168. function _withDefaultResolver(auth, resolverOverride) {
  8169. if (resolverOverride) {
  8170. return _getInstance(resolverOverride);
  8171. }
  8172. _assert(auth._popupRedirectResolver, auth, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  8173. return auth._popupRedirectResolver;
  8174. }
  8175. /**
  8176. * @license
  8177. * Copyright 2019 Google LLC
  8178. *
  8179. * Licensed under the Apache License, Version 2.0 (the "License");
  8180. * you may not use this file except in compliance with the License.
  8181. * You may obtain a copy of the License at
  8182. *
  8183. * http://www.apache.org/licenses/LICENSE-2.0
  8184. *
  8185. * Unless required by applicable law or agreed to in writing, software
  8186. * distributed under the License is distributed on an "AS IS" BASIS,
  8187. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8188. * See the License for the specific language governing permissions and
  8189. * limitations under the License.
  8190. */
  8191. class IdpCredential extends AuthCredential {
  8192. constructor(params) {
  8193. super("custom" /* ProviderId.CUSTOM */, "custom" /* ProviderId.CUSTOM */);
  8194. this.params = params;
  8195. }
  8196. _getIdTokenResponse(auth) {
  8197. return signInWithIdp(auth, this._buildIdpRequest());
  8198. }
  8199. _linkToIdToken(auth, idToken) {
  8200. return signInWithIdp(auth, this._buildIdpRequest(idToken));
  8201. }
  8202. _getReauthenticationResolver(auth) {
  8203. return signInWithIdp(auth, this._buildIdpRequest());
  8204. }
  8205. _buildIdpRequest(idToken) {
  8206. const request = {
  8207. requestUri: this.params.requestUri,
  8208. sessionId: this.params.sessionId,
  8209. postBody: this.params.postBody,
  8210. tenantId: this.params.tenantId,
  8211. pendingToken: this.params.pendingToken,
  8212. returnSecureToken: true,
  8213. returnIdpCredential: true
  8214. };
  8215. if (idToken) {
  8216. request.idToken = idToken;
  8217. }
  8218. return request;
  8219. }
  8220. }
  8221. function _signIn(params) {
  8222. return _signInWithCredential(params.auth, new IdpCredential(params), params.bypassAuthState);
  8223. }
  8224. function _reauth(params) {
  8225. const { auth, user } = params;
  8226. _assert(user, auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  8227. return _reauthenticate(user, new IdpCredential(params), params.bypassAuthState);
  8228. }
  8229. async function _link(params) {
  8230. const { auth, user } = params;
  8231. _assert(user, auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  8232. return _link$1(user, new IdpCredential(params), params.bypassAuthState);
  8233. }
  8234. /**
  8235. * @license
  8236. * Copyright 2020 Google LLC
  8237. *
  8238. * Licensed under the Apache License, Version 2.0 (the "License");
  8239. * you may not use this file except in compliance with the License.
  8240. * You may obtain a copy of the License at
  8241. *
  8242. * http://www.apache.org/licenses/LICENSE-2.0
  8243. *
  8244. * Unless required by applicable law or agreed to in writing, software
  8245. * distributed under the License is distributed on an "AS IS" BASIS,
  8246. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8247. * See the License for the specific language governing permissions and
  8248. * limitations under the License.
  8249. */
  8250. /**
  8251. * Popup event manager. Handles the popup's entire lifecycle; listens to auth
  8252. * events
  8253. */
  8254. class AbstractPopupRedirectOperation {
  8255. constructor(auth, filter, resolver, user, bypassAuthState = false) {
  8256. this.auth = auth;
  8257. this.resolver = resolver;
  8258. this.user = user;
  8259. this.bypassAuthState = bypassAuthState;
  8260. this.pendingPromise = null;
  8261. this.eventManager = null;
  8262. this.filter = Array.isArray(filter) ? filter : [filter];
  8263. }
  8264. execute() {
  8265. return new Promise(async (resolve, reject) => {
  8266. this.pendingPromise = { resolve, reject };
  8267. try {
  8268. this.eventManager = await this.resolver._initialize(this.auth);
  8269. await this.onExecution();
  8270. this.eventManager.registerConsumer(this);
  8271. }
  8272. catch (e) {
  8273. this.reject(e);
  8274. }
  8275. });
  8276. }
  8277. async onAuthEvent(event) {
  8278. const { urlResponse, sessionId, postBody, tenantId, error, type } = event;
  8279. if (error) {
  8280. this.reject(error);
  8281. return;
  8282. }
  8283. const params = {
  8284. auth: this.auth,
  8285. requestUri: urlResponse,
  8286. sessionId: sessionId,
  8287. tenantId: tenantId || undefined,
  8288. postBody: postBody || undefined,
  8289. user: this.user,
  8290. bypassAuthState: this.bypassAuthState
  8291. };
  8292. try {
  8293. this.resolve(await this.getIdpTask(type)(params));
  8294. }
  8295. catch (e) {
  8296. this.reject(e);
  8297. }
  8298. }
  8299. onError(error) {
  8300. this.reject(error);
  8301. }
  8302. getIdpTask(type) {
  8303. switch (type) {
  8304. case "signInViaPopup" /* AuthEventType.SIGN_IN_VIA_POPUP */:
  8305. case "signInViaRedirect" /* AuthEventType.SIGN_IN_VIA_REDIRECT */:
  8306. return _signIn;
  8307. case "linkViaPopup" /* AuthEventType.LINK_VIA_POPUP */:
  8308. case "linkViaRedirect" /* AuthEventType.LINK_VIA_REDIRECT */:
  8309. return _link;
  8310. case "reauthViaPopup" /* AuthEventType.REAUTH_VIA_POPUP */:
  8311. case "reauthViaRedirect" /* AuthEventType.REAUTH_VIA_REDIRECT */:
  8312. return _reauth;
  8313. default:
  8314. _fail(this.auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  8315. }
  8316. }
  8317. resolve(cred) {
  8318. debugAssert(this.pendingPromise, 'Pending promise was never set');
  8319. this.pendingPromise.resolve(cred);
  8320. this.unregisterAndCleanUp();
  8321. }
  8322. reject(error) {
  8323. debugAssert(this.pendingPromise, 'Pending promise was never set');
  8324. this.pendingPromise.reject(error);
  8325. this.unregisterAndCleanUp();
  8326. }
  8327. unregisterAndCleanUp() {
  8328. if (this.eventManager) {
  8329. this.eventManager.unregisterConsumer(this);
  8330. }
  8331. this.pendingPromise = null;
  8332. this.cleanUp();
  8333. }
  8334. }
  8335. /**
  8336. * @license
  8337. * Copyright 2020 Google LLC
  8338. *
  8339. * Licensed under the Apache License, Version 2.0 (the "License");
  8340. * you may not use this file except in compliance with the License.
  8341. * You may obtain a copy of the License at
  8342. *
  8343. * http://www.apache.org/licenses/LICENSE-2.0
  8344. *
  8345. * Unless required by applicable law or agreed to in writing, software
  8346. * distributed under the License is distributed on an "AS IS" BASIS,
  8347. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8348. * See the License for the specific language governing permissions and
  8349. * limitations under the License.
  8350. */
  8351. const _POLL_WINDOW_CLOSE_TIMEOUT = new Delay(2000, 10000);
  8352. /**
  8353. * Authenticates a Firebase client using a popup-based OAuth authentication flow.
  8354. *
  8355. * @remarks
  8356. * If succeeds, returns the signed in user along with the provider's credential. If sign in was
  8357. * unsuccessful, returns an error object containing additional information about the error.
  8358. *
  8359. * @example
  8360. * ```javascript
  8361. * // Sign in using a popup.
  8362. * const provider = new FacebookAuthProvider();
  8363. * const result = await signInWithPopup(auth, provider);
  8364. *
  8365. * // The signed-in user info.
  8366. * const user = result.user;
  8367. * // This gives you a Facebook Access Token.
  8368. * const credential = provider.credentialFromResult(auth, result);
  8369. * const token = credential.accessToken;
  8370. * ```
  8371. *
  8372. * @param auth - The {@link Auth} instance.
  8373. * @param provider - The provider to authenticate. The provider has to be an {@link OAuthProvider}.
  8374. * Non-OAuth providers like {@link EmailAuthProvider} will throw an error.
  8375. * @param resolver - An instance of {@link PopupRedirectResolver}, optional
  8376. * if already supplied to {@link initializeAuth} or provided by {@link getAuth}.
  8377. *
  8378. *
  8379. * @public
  8380. */
  8381. async function signInWithPopup(auth, provider, resolver) {
  8382. const authInternal = _castAuth(auth);
  8383. _assertInstanceOf(auth, provider, FederatedAuthProvider);
  8384. const resolverInternal = _withDefaultResolver(authInternal, resolver);
  8385. const action = new PopupOperation(authInternal, "signInViaPopup" /* AuthEventType.SIGN_IN_VIA_POPUP */, provider, resolverInternal);
  8386. return action.executeNotNull();
  8387. }
  8388. /**
  8389. * Reauthenticates the current user with the specified {@link OAuthProvider} using a pop-up based
  8390. * OAuth flow.
  8391. *
  8392. * @remarks
  8393. * If the reauthentication is successful, the returned result will contain the user and the
  8394. * provider's credential.
  8395. *
  8396. * @example
  8397. * ```javascript
  8398. * // Sign in using a popup.
  8399. * const provider = new FacebookAuthProvider();
  8400. * const result = await signInWithPopup(auth, provider);
  8401. * // Reauthenticate using a popup.
  8402. * await reauthenticateWithPopup(result.user, provider);
  8403. * ```
  8404. *
  8405. * @param user - The user.
  8406. * @param provider - The provider to authenticate. The provider has to be an {@link OAuthProvider}.
  8407. * Non-OAuth providers like {@link EmailAuthProvider} will throw an error.
  8408. * @param resolver - An instance of {@link PopupRedirectResolver}, optional
  8409. * if already supplied to {@link initializeAuth} or provided by {@link getAuth}.
  8410. *
  8411. * @public
  8412. */
  8413. async function reauthenticateWithPopup(user, provider, resolver) {
  8414. const userInternal = util.getModularInstance(user);
  8415. _assertInstanceOf(userInternal.auth, provider, FederatedAuthProvider);
  8416. const resolverInternal = _withDefaultResolver(userInternal.auth, resolver);
  8417. const action = new PopupOperation(userInternal.auth, "reauthViaPopup" /* AuthEventType.REAUTH_VIA_POPUP */, provider, resolverInternal, userInternal);
  8418. return action.executeNotNull();
  8419. }
  8420. /**
  8421. * Links the authenticated provider to the user account using a pop-up based OAuth flow.
  8422. *
  8423. * @remarks
  8424. * If the linking is successful, the returned result will contain the user and the provider's credential.
  8425. *
  8426. *
  8427. * @example
  8428. * ```javascript
  8429. * // Sign in using some other provider.
  8430. * const result = await signInWithEmailAndPassword(auth, email, password);
  8431. * // Link using a popup.
  8432. * const provider = new FacebookAuthProvider();
  8433. * await linkWithPopup(result.user, provider);
  8434. * ```
  8435. *
  8436. * @param user - The user.
  8437. * @param provider - The provider to authenticate. The provider has to be an {@link OAuthProvider}.
  8438. * Non-OAuth providers like {@link EmailAuthProvider} will throw an error.
  8439. * @param resolver - An instance of {@link PopupRedirectResolver}, optional
  8440. * if already supplied to {@link initializeAuth} or provided by {@link getAuth}.
  8441. *
  8442. * @public
  8443. */
  8444. async function linkWithPopup(user, provider, resolver) {
  8445. const userInternal = util.getModularInstance(user);
  8446. _assertInstanceOf(userInternal.auth, provider, FederatedAuthProvider);
  8447. const resolverInternal = _withDefaultResolver(userInternal.auth, resolver);
  8448. const action = new PopupOperation(userInternal.auth, "linkViaPopup" /* AuthEventType.LINK_VIA_POPUP */, provider, resolverInternal, userInternal);
  8449. return action.executeNotNull();
  8450. }
  8451. /**
  8452. * Popup event manager. Handles the popup's entire lifecycle; listens to auth
  8453. * events
  8454. *
  8455. */
  8456. class PopupOperation extends AbstractPopupRedirectOperation {
  8457. constructor(auth, filter, provider, resolver, user) {
  8458. super(auth, filter, resolver, user);
  8459. this.provider = provider;
  8460. this.authWindow = null;
  8461. this.pollId = null;
  8462. if (PopupOperation.currentPopupAction) {
  8463. PopupOperation.currentPopupAction.cancel();
  8464. }
  8465. PopupOperation.currentPopupAction = this;
  8466. }
  8467. async executeNotNull() {
  8468. const result = await this.execute();
  8469. _assert(result, this.auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  8470. return result;
  8471. }
  8472. async onExecution() {
  8473. debugAssert(this.filter.length === 1, 'Popup operations only handle one event');
  8474. const eventId = _generateEventId();
  8475. this.authWindow = await this.resolver._openPopup(this.auth, this.provider, this.filter[0], // There's always one, see constructor
  8476. eventId);
  8477. this.authWindow.associatedEvent = eventId;
  8478. // Check for web storage support and origin validation _after_ the popup is
  8479. // loaded. These operations are slow (~1 second or so) Rather than
  8480. // waiting on them before opening the window, optimistically open the popup
  8481. // and check for storage support at the same time. If storage support is
  8482. // not available, this will cause the whole thing to reject properly. It
  8483. // will also close the popup, but since the promise has already rejected,
  8484. // the popup closed by user poll will reject into the void.
  8485. this.resolver._originValidation(this.auth).catch(e => {
  8486. this.reject(e);
  8487. });
  8488. this.resolver._isIframeWebStorageSupported(this.auth, isSupported => {
  8489. if (!isSupported) {
  8490. this.reject(_createError(this.auth, "web-storage-unsupported" /* AuthErrorCode.WEB_STORAGE_UNSUPPORTED */));
  8491. }
  8492. });
  8493. // Handle user closure. Notice this does *not* use await
  8494. this.pollUserCancellation();
  8495. }
  8496. get eventId() {
  8497. var _a;
  8498. return ((_a = this.authWindow) === null || _a === void 0 ? void 0 : _a.associatedEvent) || null;
  8499. }
  8500. cancel() {
  8501. this.reject(_createError(this.auth, "cancelled-popup-request" /* AuthErrorCode.EXPIRED_POPUP_REQUEST */));
  8502. }
  8503. cleanUp() {
  8504. if (this.authWindow) {
  8505. this.authWindow.close();
  8506. }
  8507. if (this.pollId) {
  8508. window.clearTimeout(this.pollId);
  8509. }
  8510. this.authWindow = null;
  8511. this.pollId = null;
  8512. PopupOperation.currentPopupAction = null;
  8513. }
  8514. pollUserCancellation() {
  8515. const poll = () => {
  8516. var _a, _b;
  8517. if ((_b = (_a = this.authWindow) === null || _a === void 0 ? void 0 : _a.window) === null || _b === void 0 ? void 0 : _b.closed) {
  8518. // Make sure that there is sufficient time for whatever action to
  8519. // complete. The window could have closed but the sign in network
  8520. // call could still be in flight. This is specifically true for
  8521. // Firefox or if the opener is in an iframe, in which case the oauth
  8522. // helper closes the popup.
  8523. this.pollId = window.setTimeout(() => {
  8524. this.pollId = null;
  8525. this.reject(_createError(this.auth, "popup-closed-by-user" /* AuthErrorCode.POPUP_CLOSED_BY_USER */));
  8526. }, 8000 /* _Timeout.AUTH_EVENT */);
  8527. return;
  8528. }
  8529. this.pollId = window.setTimeout(poll, _POLL_WINDOW_CLOSE_TIMEOUT.get());
  8530. };
  8531. poll();
  8532. }
  8533. }
  8534. // Only one popup is ever shown at once. The lifecycle of the current popup
  8535. // can be managed / cancelled by the constructor.
  8536. PopupOperation.currentPopupAction = null;
  8537. /**
  8538. * @license
  8539. * Copyright 2020 Google LLC
  8540. *
  8541. * Licensed under the Apache License, Version 2.0 (the "License");
  8542. * you may not use this file except in compliance with the License.
  8543. * You may obtain a copy of the License at
  8544. *
  8545. * http://www.apache.org/licenses/LICENSE-2.0
  8546. *
  8547. * Unless required by applicable law or agreed to in writing, software
  8548. * distributed under the License is distributed on an "AS IS" BASIS,
  8549. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8550. * See the License for the specific language governing permissions and
  8551. * limitations under the License.
  8552. */
  8553. const PENDING_REDIRECT_KEY = 'pendingRedirect';
  8554. // We only get one redirect outcome for any one auth, so just store it
  8555. // in here.
  8556. const redirectOutcomeMap = new Map();
  8557. class RedirectAction extends AbstractPopupRedirectOperation {
  8558. constructor(auth, resolver, bypassAuthState = false) {
  8559. super(auth, [
  8560. "signInViaRedirect" /* AuthEventType.SIGN_IN_VIA_REDIRECT */,
  8561. "linkViaRedirect" /* AuthEventType.LINK_VIA_REDIRECT */,
  8562. "reauthViaRedirect" /* AuthEventType.REAUTH_VIA_REDIRECT */,
  8563. "unknown" /* AuthEventType.UNKNOWN */
  8564. ], resolver, undefined, bypassAuthState);
  8565. this.eventId = null;
  8566. }
  8567. /**
  8568. * Override the execute function; if we already have a redirect result, then
  8569. * just return it.
  8570. */
  8571. async execute() {
  8572. let readyOutcome = redirectOutcomeMap.get(this.auth._key());
  8573. if (!readyOutcome) {
  8574. try {
  8575. const hasPendingRedirect = await _getAndClearPendingRedirectStatus(this.resolver, this.auth);
  8576. const result = hasPendingRedirect ? await super.execute() : null;
  8577. readyOutcome = () => Promise.resolve(result);
  8578. }
  8579. catch (e) {
  8580. readyOutcome = () => Promise.reject(e);
  8581. }
  8582. redirectOutcomeMap.set(this.auth._key(), readyOutcome);
  8583. }
  8584. // If we're not bypassing auth state, the ready outcome should be set to
  8585. // null.
  8586. if (!this.bypassAuthState) {
  8587. redirectOutcomeMap.set(this.auth._key(), () => Promise.resolve(null));
  8588. }
  8589. return readyOutcome();
  8590. }
  8591. async onAuthEvent(event) {
  8592. if (event.type === "signInViaRedirect" /* AuthEventType.SIGN_IN_VIA_REDIRECT */) {
  8593. return super.onAuthEvent(event);
  8594. }
  8595. else if (event.type === "unknown" /* AuthEventType.UNKNOWN */) {
  8596. // This is a sentinel value indicating there's no pending redirect
  8597. this.resolve(null);
  8598. return;
  8599. }
  8600. if (event.eventId) {
  8601. const user = await this.auth._redirectUserForId(event.eventId);
  8602. if (user) {
  8603. this.user = user;
  8604. return super.onAuthEvent(event);
  8605. }
  8606. else {
  8607. this.resolve(null);
  8608. }
  8609. }
  8610. }
  8611. async onExecution() { }
  8612. cleanUp() { }
  8613. }
  8614. async function _getAndClearPendingRedirectStatus(resolver, auth) {
  8615. const key = pendingRedirectKey(auth);
  8616. const persistence = resolverPersistence(resolver);
  8617. if (!(await persistence._isAvailable())) {
  8618. return false;
  8619. }
  8620. const hasPendingRedirect = (await persistence._get(key)) === 'true';
  8621. await persistence._remove(key);
  8622. return hasPendingRedirect;
  8623. }
  8624. async function _setPendingRedirectStatus(resolver, auth) {
  8625. return resolverPersistence(resolver)._set(pendingRedirectKey(auth), 'true');
  8626. }
  8627. function _clearRedirectOutcomes() {
  8628. redirectOutcomeMap.clear();
  8629. }
  8630. function _overrideRedirectResult(auth, result) {
  8631. redirectOutcomeMap.set(auth._key(), result);
  8632. }
  8633. function resolverPersistence(resolver) {
  8634. return _getInstance(resolver._redirectPersistence);
  8635. }
  8636. function pendingRedirectKey(auth) {
  8637. return _persistenceKeyName(PENDING_REDIRECT_KEY, auth.config.apiKey, auth.name);
  8638. }
  8639. /**
  8640. * @license
  8641. * Copyright 2020 Google LLC
  8642. *
  8643. * Licensed under the Apache License, Version 2.0 (the "License");
  8644. * you may not use this file except in compliance with the License.
  8645. * You may obtain a copy of the License at
  8646. *
  8647. * http://www.apache.org/licenses/LICENSE-2.0
  8648. *
  8649. * Unless required by applicable law or agreed to in writing, software
  8650. * distributed under the License is distributed on an "AS IS" BASIS,
  8651. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8652. * See the License for the specific language governing permissions and
  8653. * limitations under the License.
  8654. */
  8655. /**
  8656. * Authenticates a Firebase client using a full-page redirect flow.
  8657. *
  8658. * @remarks
  8659. * To handle the results and errors for this operation, refer to {@link getRedirectResult}.
  8660. * Follow the {@link https://firebase.google.com/docs/auth/web/redirect-best-practices
  8661. * | best practices} when using {@link signInWithRedirect}.
  8662. *
  8663. * @example
  8664. * ```javascript
  8665. * // Sign in using a redirect.
  8666. * const provider = new FacebookAuthProvider();
  8667. * // You can add additional scopes to the provider:
  8668. * provider.addScope('user_birthday');
  8669. * // Start a sign in process for an unauthenticated user.
  8670. * await signInWithRedirect(auth, provider);
  8671. * // This will trigger a full page redirect away from your app
  8672. *
  8673. * // After returning from the redirect when your app initializes you can obtain the result
  8674. * const result = await getRedirectResult(auth);
  8675. * if (result) {
  8676. * // This is the signed-in user
  8677. * const user = result.user;
  8678. * // This gives you a Facebook Access Token.
  8679. * const credential = provider.credentialFromResult(auth, result);
  8680. * const token = credential.accessToken;
  8681. * }
  8682. * // As this API can be used for sign-in, linking and reauthentication,
  8683. * // check the operationType to determine what triggered this redirect
  8684. * // operation.
  8685. * const operationType = result.operationType;
  8686. * ```
  8687. *
  8688. * @param auth - The {@link Auth} instance.
  8689. * @param provider - The provider to authenticate. The provider has to be an {@link OAuthProvider}.
  8690. * Non-OAuth providers like {@link EmailAuthProvider} will throw an error.
  8691. * @param resolver - An instance of {@link PopupRedirectResolver}, optional
  8692. * if already supplied to {@link initializeAuth} or provided by {@link getAuth}.
  8693. *
  8694. * @public
  8695. */
  8696. function signInWithRedirect(auth, provider, resolver) {
  8697. return _signInWithRedirect(auth, provider, resolver);
  8698. }
  8699. async function _signInWithRedirect(auth, provider, resolver) {
  8700. const authInternal = _castAuth(auth);
  8701. _assertInstanceOf(auth, provider, FederatedAuthProvider);
  8702. // Wait for auth initialization to complete, this will process pending redirects and clear the
  8703. // PENDING_REDIRECT_KEY in persistence. This should be completed before starting a new
  8704. // redirect and creating a PENDING_REDIRECT_KEY entry.
  8705. await authInternal._initializationPromise;
  8706. const resolverInternal = _withDefaultResolver(authInternal, resolver);
  8707. await _setPendingRedirectStatus(resolverInternal, authInternal);
  8708. return resolverInternal._openRedirect(authInternal, provider, "signInViaRedirect" /* AuthEventType.SIGN_IN_VIA_REDIRECT */);
  8709. }
  8710. /**
  8711. * Reauthenticates the current user with the specified {@link OAuthProvider} using a full-page redirect flow.
  8712. * @remarks
  8713. * To handle the results and errors for this operation, refer to {@link getRedirectResult}.
  8714. * Follow the {@link https://firebase.google.com/docs/auth/web/redirect-best-practices
  8715. * | best practices} when using {@link reauthenticateWithRedirect}.
  8716. *
  8717. * @example
  8718. * ```javascript
  8719. * // Sign in using a redirect.
  8720. * const provider = new FacebookAuthProvider();
  8721. * const result = await signInWithRedirect(auth, provider);
  8722. * // This will trigger a full page redirect away from your app
  8723. *
  8724. * // After returning from the redirect when your app initializes you can obtain the result
  8725. * const result = await getRedirectResult(auth);
  8726. * // Reauthenticate using a redirect.
  8727. * await reauthenticateWithRedirect(result.user, provider);
  8728. * // This will again trigger a full page redirect away from your app
  8729. *
  8730. * // After returning from the redirect when your app initializes you can obtain the result
  8731. * const result = await getRedirectResult(auth);
  8732. * ```
  8733. *
  8734. * @param user - The user.
  8735. * @param provider - The provider to authenticate. The provider has to be an {@link OAuthProvider}.
  8736. * Non-OAuth providers like {@link EmailAuthProvider} will throw an error.
  8737. * @param resolver - An instance of {@link PopupRedirectResolver}, optional
  8738. * if already supplied to {@link initializeAuth} or provided by {@link getAuth}.
  8739. *
  8740. * @public
  8741. */
  8742. function reauthenticateWithRedirect(user, provider, resolver) {
  8743. return _reauthenticateWithRedirect(user, provider, resolver);
  8744. }
  8745. async function _reauthenticateWithRedirect(user, provider, resolver) {
  8746. const userInternal = util.getModularInstance(user);
  8747. _assertInstanceOf(userInternal.auth, provider, FederatedAuthProvider);
  8748. // Wait for auth initialization to complete, this will process pending redirects and clear the
  8749. // PENDING_REDIRECT_KEY in persistence. This should be completed before starting a new
  8750. // redirect and creating a PENDING_REDIRECT_KEY entry.
  8751. await userInternal.auth._initializationPromise;
  8752. // Allow the resolver to error before persisting the redirect user
  8753. const resolverInternal = _withDefaultResolver(userInternal.auth, resolver);
  8754. await _setPendingRedirectStatus(resolverInternal, userInternal.auth);
  8755. const eventId = await prepareUserForRedirect(userInternal);
  8756. return resolverInternal._openRedirect(userInternal.auth, provider, "reauthViaRedirect" /* AuthEventType.REAUTH_VIA_REDIRECT */, eventId);
  8757. }
  8758. /**
  8759. * Links the {@link OAuthProvider} to the user account using a full-page redirect flow.
  8760. * @remarks
  8761. * To handle the results and errors for this operation, refer to {@link getRedirectResult}.
  8762. * Follow the {@link https://firebase.google.com/docs/auth/web/redirect-best-practices
  8763. * | best practices} when using {@link linkWithRedirect}.
  8764. *
  8765. * @example
  8766. * ```javascript
  8767. * // Sign in using some other provider.
  8768. * const result = await signInWithEmailAndPassword(auth, email, password);
  8769. * // Link using a redirect.
  8770. * const provider = new FacebookAuthProvider();
  8771. * await linkWithRedirect(result.user, provider);
  8772. * // This will trigger a full page redirect away from your app
  8773. *
  8774. * // After returning from the redirect when your app initializes you can obtain the result
  8775. * const result = await getRedirectResult(auth);
  8776. * ```
  8777. *
  8778. * @param user - The user.
  8779. * @param provider - The provider to authenticate. The provider has to be an {@link OAuthProvider}.
  8780. * Non-OAuth providers like {@link EmailAuthProvider} will throw an error.
  8781. * @param resolver - An instance of {@link PopupRedirectResolver}, optional
  8782. * if already supplied to {@link initializeAuth} or provided by {@link getAuth}.
  8783. *
  8784. *
  8785. * @public
  8786. */
  8787. function linkWithRedirect(user, provider, resolver) {
  8788. return _linkWithRedirect(user, provider, resolver);
  8789. }
  8790. async function _linkWithRedirect(user, provider, resolver) {
  8791. const userInternal = util.getModularInstance(user);
  8792. _assertInstanceOf(userInternal.auth, provider, FederatedAuthProvider);
  8793. // Wait for auth initialization to complete, this will process pending redirects and clear the
  8794. // PENDING_REDIRECT_KEY in persistence. This should be completed before starting a new
  8795. // redirect and creating a PENDING_REDIRECT_KEY entry.
  8796. await userInternal.auth._initializationPromise;
  8797. // Allow the resolver to error before persisting the redirect user
  8798. const resolverInternal = _withDefaultResolver(userInternal.auth, resolver);
  8799. await _assertLinkedStatus(false, userInternal, provider.providerId);
  8800. await _setPendingRedirectStatus(resolverInternal, userInternal.auth);
  8801. const eventId = await prepareUserForRedirect(userInternal);
  8802. return resolverInternal._openRedirect(userInternal.auth, provider, "linkViaRedirect" /* AuthEventType.LINK_VIA_REDIRECT */, eventId);
  8803. }
  8804. /**
  8805. * Returns a {@link UserCredential} from the redirect-based sign-in flow.
  8806. *
  8807. * @remarks
  8808. * If sign-in succeeded, returns the signed in user. If sign-in was unsuccessful, fails with an
  8809. * error. If no redirect operation was called, returns `null`.
  8810. *
  8811. * @example
  8812. * ```javascript
  8813. * // Sign in using a redirect.
  8814. * const provider = new FacebookAuthProvider();
  8815. * // You can add additional scopes to the provider:
  8816. * provider.addScope('user_birthday');
  8817. * // Start a sign in process for an unauthenticated user.
  8818. * await signInWithRedirect(auth, provider);
  8819. * // This will trigger a full page redirect away from your app
  8820. *
  8821. * // After returning from the redirect when your app initializes you can obtain the result
  8822. * const result = await getRedirectResult(auth);
  8823. * if (result) {
  8824. * // This is the signed-in user
  8825. * const user = result.user;
  8826. * // This gives you a Facebook Access Token.
  8827. * const credential = provider.credentialFromResult(auth, result);
  8828. * const token = credential.accessToken;
  8829. * }
  8830. * // As this API can be used for sign-in, linking and reauthentication,
  8831. * // check the operationType to determine what triggered this redirect
  8832. * // operation.
  8833. * const operationType = result.operationType;
  8834. * ```
  8835. *
  8836. * @param auth - The {@link Auth} instance.
  8837. * @param resolver - An instance of {@link PopupRedirectResolver}, optional
  8838. * if already supplied to {@link initializeAuth} or provided by {@link getAuth}.
  8839. *
  8840. * @public
  8841. */
  8842. async function getRedirectResult(auth, resolver) {
  8843. await _castAuth(auth)._initializationPromise;
  8844. return _getRedirectResult(auth, resolver, false);
  8845. }
  8846. async function _getRedirectResult(auth, resolverExtern, bypassAuthState = false) {
  8847. const authInternal = _castAuth(auth);
  8848. const resolver = _withDefaultResolver(authInternal, resolverExtern);
  8849. const action = new RedirectAction(authInternal, resolver, bypassAuthState);
  8850. const result = await action.execute();
  8851. if (result && !bypassAuthState) {
  8852. delete result.user._redirectEventId;
  8853. await authInternal._persistUserIfCurrent(result.user);
  8854. await authInternal._setRedirectUser(null, resolverExtern);
  8855. }
  8856. return result;
  8857. }
  8858. async function prepareUserForRedirect(user) {
  8859. const eventId = _generateEventId(`${user.uid}:::`);
  8860. user._redirectEventId = eventId;
  8861. await user.auth._setRedirectUser(user);
  8862. await user.auth._persistUserIfCurrent(user);
  8863. return eventId;
  8864. }
  8865. /**
  8866. * @license
  8867. * Copyright 2020 Google LLC
  8868. *
  8869. * Licensed under the Apache License, Version 2.0 (the "License");
  8870. * you may not use this file except in compliance with the License.
  8871. * You may obtain a copy of the License at
  8872. *
  8873. * http://www.apache.org/licenses/LICENSE-2.0
  8874. *
  8875. * Unless required by applicable law or agreed to in writing, software
  8876. * distributed under the License is distributed on an "AS IS" BASIS,
  8877. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8878. * See the License for the specific language governing permissions and
  8879. * limitations under the License.
  8880. */
  8881. // The amount of time to store the UIDs of seen events; this is
  8882. // set to 10 min by default
  8883. const EVENT_DUPLICATION_CACHE_DURATION_MS = 10 * 60 * 1000;
  8884. class AuthEventManager {
  8885. constructor(auth) {
  8886. this.auth = auth;
  8887. this.cachedEventUids = new Set();
  8888. this.consumers = new Set();
  8889. this.queuedRedirectEvent = null;
  8890. this.hasHandledPotentialRedirect = false;
  8891. this.lastProcessedEventTime = Date.now();
  8892. }
  8893. registerConsumer(authEventConsumer) {
  8894. this.consumers.add(authEventConsumer);
  8895. if (this.queuedRedirectEvent &&
  8896. this.isEventForConsumer(this.queuedRedirectEvent, authEventConsumer)) {
  8897. this.sendToConsumer(this.queuedRedirectEvent, authEventConsumer);
  8898. this.saveEventToCache(this.queuedRedirectEvent);
  8899. this.queuedRedirectEvent = null;
  8900. }
  8901. }
  8902. unregisterConsumer(authEventConsumer) {
  8903. this.consumers.delete(authEventConsumer);
  8904. }
  8905. onEvent(event) {
  8906. // Check if the event has already been handled
  8907. if (this.hasEventBeenHandled(event)) {
  8908. return false;
  8909. }
  8910. let handled = false;
  8911. this.consumers.forEach(consumer => {
  8912. if (this.isEventForConsumer(event, consumer)) {
  8913. handled = true;
  8914. this.sendToConsumer(event, consumer);
  8915. this.saveEventToCache(event);
  8916. }
  8917. });
  8918. if (this.hasHandledPotentialRedirect || !isRedirectEvent(event)) {
  8919. // If we've already seen a redirect before, or this is a popup event,
  8920. // bail now
  8921. return handled;
  8922. }
  8923. this.hasHandledPotentialRedirect = true;
  8924. // If the redirect wasn't handled, hang on to it
  8925. if (!handled) {
  8926. this.queuedRedirectEvent = event;
  8927. handled = true;
  8928. }
  8929. return handled;
  8930. }
  8931. sendToConsumer(event, consumer) {
  8932. var _a;
  8933. if (event.error && !isNullRedirectEvent(event)) {
  8934. const code = ((_a = event.error.code) === null || _a === void 0 ? void 0 : _a.split('auth/')[1]) ||
  8935. "internal-error" /* AuthErrorCode.INTERNAL_ERROR */;
  8936. consumer.onError(_createError(this.auth, code));
  8937. }
  8938. else {
  8939. consumer.onAuthEvent(event);
  8940. }
  8941. }
  8942. isEventForConsumer(event, consumer) {
  8943. const eventIdMatches = consumer.eventId === null ||
  8944. (!!event.eventId && event.eventId === consumer.eventId);
  8945. return consumer.filter.includes(event.type) && eventIdMatches;
  8946. }
  8947. hasEventBeenHandled(event) {
  8948. if (Date.now() - this.lastProcessedEventTime >=
  8949. EVENT_DUPLICATION_CACHE_DURATION_MS) {
  8950. this.cachedEventUids.clear();
  8951. }
  8952. return this.cachedEventUids.has(eventUid(event));
  8953. }
  8954. saveEventToCache(event) {
  8955. this.cachedEventUids.add(eventUid(event));
  8956. this.lastProcessedEventTime = Date.now();
  8957. }
  8958. }
  8959. function eventUid(e) {
  8960. return [e.type, e.eventId, e.sessionId, e.tenantId].filter(v => v).join('-');
  8961. }
  8962. function isNullRedirectEvent({ type, error }) {
  8963. return (type === "unknown" /* AuthEventType.UNKNOWN */ &&
  8964. (error === null || error === void 0 ? void 0 : error.code) === `auth/${"no-auth-event" /* AuthErrorCode.NO_AUTH_EVENT */}`);
  8965. }
  8966. function isRedirectEvent(event) {
  8967. switch (event.type) {
  8968. case "signInViaRedirect" /* AuthEventType.SIGN_IN_VIA_REDIRECT */:
  8969. case "linkViaRedirect" /* AuthEventType.LINK_VIA_REDIRECT */:
  8970. case "reauthViaRedirect" /* AuthEventType.REAUTH_VIA_REDIRECT */:
  8971. return true;
  8972. case "unknown" /* AuthEventType.UNKNOWN */:
  8973. return isNullRedirectEvent(event);
  8974. default:
  8975. return false;
  8976. }
  8977. }
  8978. /**
  8979. * @license
  8980. * Copyright 2020 Google LLC
  8981. *
  8982. * Licensed under the Apache License, Version 2.0 (the "License");
  8983. * you may not use this file except in compliance with the License.
  8984. * You may obtain a copy of the License at
  8985. *
  8986. * http://www.apache.org/licenses/LICENSE-2.0
  8987. *
  8988. * Unless required by applicable law or agreed to in writing, software
  8989. * distributed under the License is distributed on an "AS IS" BASIS,
  8990. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  8991. * See the License for the specific language governing permissions and
  8992. * limitations under the License.
  8993. */
  8994. async function _getProjectConfig(auth, request = {}) {
  8995. return _performApiRequest(auth, "GET" /* HttpMethod.GET */, "/v1/projects" /* Endpoint.GET_PROJECT_CONFIG */, request);
  8996. }
  8997. /**
  8998. * @license
  8999. * Copyright 2020 Google LLC
  9000. *
  9001. * Licensed under the Apache License, Version 2.0 (the "License");
  9002. * you may not use this file except in compliance with the License.
  9003. * You may obtain a copy of the License at
  9004. *
  9005. * http://www.apache.org/licenses/LICENSE-2.0
  9006. *
  9007. * Unless required by applicable law or agreed to in writing, software
  9008. * distributed under the License is distributed on an "AS IS" BASIS,
  9009. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9010. * See the License for the specific language governing permissions and
  9011. * limitations under the License.
  9012. */
  9013. const IP_ADDRESS_REGEX = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
  9014. const HTTP_REGEX = /^https?/;
  9015. async function _validateOrigin(auth) {
  9016. // Skip origin validation if we are in an emulated environment
  9017. if (auth.config.emulator) {
  9018. return;
  9019. }
  9020. const { authorizedDomains } = await _getProjectConfig(auth);
  9021. for (const domain of authorizedDomains) {
  9022. try {
  9023. if (matchDomain(domain)) {
  9024. return;
  9025. }
  9026. }
  9027. catch (_a) {
  9028. // Do nothing if there's a URL error; just continue searching
  9029. }
  9030. }
  9031. // In the old SDK, this error also provides helpful messages.
  9032. _fail(auth, "unauthorized-domain" /* AuthErrorCode.INVALID_ORIGIN */);
  9033. }
  9034. function matchDomain(expected) {
  9035. const currentUrl = _getCurrentUrl();
  9036. const { protocol, hostname } = new URL(currentUrl);
  9037. if (expected.startsWith('chrome-extension://')) {
  9038. const ceUrl = new URL(expected);
  9039. if (ceUrl.hostname === '' && hostname === '') {
  9040. // For some reason we're not parsing chrome URLs properly
  9041. return (protocol === 'chrome-extension:' &&
  9042. expected.replace('chrome-extension://', '') ===
  9043. currentUrl.replace('chrome-extension://', ''));
  9044. }
  9045. return protocol === 'chrome-extension:' && ceUrl.hostname === hostname;
  9046. }
  9047. if (!HTTP_REGEX.test(protocol)) {
  9048. return false;
  9049. }
  9050. if (IP_ADDRESS_REGEX.test(expected)) {
  9051. // The domain has to be exactly equal to the pattern, as an IP domain will
  9052. // only contain the IP, no extra character.
  9053. return hostname === expected;
  9054. }
  9055. // Dots in pattern should be escaped.
  9056. const escapedDomainPattern = expected.replace(/\./g, '\\.');
  9057. // Non ip address domains.
  9058. // domain.com = *.domain.com OR domain.com
  9059. const re = new RegExp('^(.+\\.' + escapedDomainPattern + '|' + escapedDomainPattern + ')$', 'i');
  9060. return re.test(hostname);
  9061. }
  9062. /**
  9063. * @license
  9064. * Copyright 2020 Google LLC.
  9065. *
  9066. * Licensed under the Apache License, Version 2.0 (the "License");
  9067. * you may not use this file except in compliance with the License.
  9068. * You may obtain a copy of the License at
  9069. *
  9070. * http://www.apache.org/licenses/LICENSE-2.0
  9071. *
  9072. * Unless required by applicable law or agreed to in writing, software
  9073. * distributed under the License is distributed on an "AS IS" BASIS,
  9074. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9075. * See the License for the specific language governing permissions and
  9076. * limitations under the License.
  9077. */
  9078. const NETWORK_TIMEOUT = new Delay(30000, 60000);
  9079. /**
  9080. * Reset unlaoded GApi modules. If gapi.load fails due to a network error,
  9081. * it will stop working after a retrial. This is a hack to fix this issue.
  9082. */
  9083. function resetUnloadedGapiModules() {
  9084. // Clear last failed gapi.load state to force next gapi.load to first
  9085. // load the failed gapi.iframes module.
  9086. // Get gapix.beacon context.
  9087. const beacon = _window().___jsl;
  9088. // Get current hint.
  9089. if (beacon === null || beacon === void 0 ? void 0 : beacon.H) {
  9090. // Get gapi hint.
  9091. for (const hint of Object.keys(beacon.H)) {
  9092. // Requested modules.
  9093. beacon.H[hint].r = beacon.H[hint].r || [];
  9094. // Loaded modules.
  9095. beacon.H[hint].L = beacon.H[hint].L || [];
  9096. // Set requested modules to a copy of the loaded modules.
  9097. beacon.H[hint].r = [...beacon.H[hint].L];
  9098. // Clear pending callbacks.
  9099. if (beacon.CP) {
  9100. for (let i = 0; i < beacon.CP.length; i++) {
  9101. // Remove all failed pending callbacks.
  9102. beacon.CP[i] = null;
  9103. }
  9104. }
  9105. }
  9106. }
  9107. }
  9108. function loadGapi(auth) {
  9109. return new Promise((resolve, reject) => {
  9110. var _a, _b, _c;
  9111. // Function to run when gapi.load is ready.
  9112. function loadGapiIframe() {
  9113. // The developer may have tried to previously run gapi.load and failed.
  9114. // Run this to fix that.
  9115. resetUnloadedGapiModules();
  9116. gapi.load('gapi.iframes', {
  9117. callback: () => {
  9118. resolve(gapi.iframes.getContext());
  9119. },
  9120. ontimeout: () => {
  9121. // The above reset may be sufficient, but having this reset after
  9122. // failure ensures that if the developer calls gapi.load after the
  9123. // connection is re-established and before another attempt to embed
  9124. // the iframe, it would work and would not be broken because of our
  9125. // failed attempt.
  9126. // Timeout when gapi.iframes.Iframe not loaded.
  9127. resetUnloadedGapiModules();
  9128. reject(_createError(auth, "network-request-failed" /* AuthErrorCode.NETWORK_REQUEST_FAILED */));
  9129. },
  9130. timeout: NETWORK_TIMEOUT.get()
  9131. });
  9132. }
  9133. if ((_b = (_a = _window().gapi) === null || _a === void 0 ? void 0 : _a.iframes) === null || _b === void 0 ? void 0 : _b.Iframe) {
  9134. // If gapi.iframes.Iframe available, resolve.
  9135. resolve(gapi.iframes.getContext());
  9136. }
  9137. else if (!!((_c = _window().gapi) === null || _c === void 0 ? void 0 : _c.load)) {
  9138. // Gapi loader ready, load gapi.iframes.
  9139. loadGapiIframe();
  9140. }
  9141. else {
  9142. // Create a new iframe callback when this is called so as not to overwrite
  9143. // any previous defined callback. This happens if this method is called
  9144. // multiple times in parallel and could result in the later callback
  9145. // overwriting the previous one. This would end up with a iframe
  9146. // timeout.
  9147. const cbName = _generateCallbackName('iframefcb');
  9148. // GApi loader not available, dynamically load platform.js.
  9149. _window()[cbName] = () => {
  9150. // GApi loader should be ready.
  9151. if (!!gapi.load) {
  9152. loadGapiIframe();
  9153. }
  9154. else {
  9155. // Gapi loader failed, throw error.
  9156. reject(_createError(auth, "network-request-failed" /* AuthErrorCode.NETWORK_REQUEST_FAILED */));
  9157. }
  9158. };
  9159. // Load GApi loader.
  9160. return _loadJS(`https://apis.google.com/js/api.js?onload=${cbName}`)
  9161. .catch(e => reject(e));
  9162. }
  9163. }).catch(error => {
  9164. // Reset cached promise to allow for retrial.
  9165. cachedGApiLoader = null;
  9166. throw error;
  9167. });
  9168. }
  9169. let cachedGApiLoader = null;
  9170. function _loadGapi(auth) {
  9171. cachedGApiLoader = cachedGApiLoader || loadGapi(auth);
  9172. return cachedGApiLoader;
  9173. }
  9174. /**
  9175. * @license
  9176. * Copyright 2020 Google LLC.
  9177. *
  9178. * Licensed under the Apache License, Version 2.0 (the "License");
  9179. * you may not use this file except in compliance with the License.
  9180. * You may obtain a copy of the License at
  9181. *
  9182. * http://www.apache.org/licenses/LICENSE-2.0
  9183. *
  9184. * Unless required by applicable law or agreed to in writing, software
  9185. * distributed under the License is distributed on an "AS IS" BASIS,
  9186. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9187. * See the License for the specific language governing permissions and
  9188. * limitations under the License.
  9189. */
  9190. const PING_TIMEOUT = new Delay(5000, 15000);
  9191. const IFRAME_PATH = '__/auth/iframe';
  9192. const EMULATED_IFRAME_PATH = 'emulator/auth/iframe';
  9193. const IFRAME_ATTRIBUTES = {
  9194. style: {
  9195. position: 'absolute',
  9196. top: '-100px',
  9197. width: '1px',
  9198. height: '1px'
  9199. },
  9200. 'aria-hidden': 'true',
  9201. tabindex: '-1'
  9202. };
  9203. // Map from apiHost to endpoint ID for passing into iframe. In current SDK, apiHost can be set to
  9204. // anything (not from a list of endpoints with IDs as in legacy), so this is the closest we can get.
  9205. const EID_FROM_APIHOST = new Map([
  9206. ["identitytoolkit.googleapis.com" /* DefaultConfig.API_HOST */, 'p'],
  9207. ['staging-identitytoolkit.sandbox.googleapis.com', 's'],
  9208. ['test-identitytoolkit.sandbox.googleapis.com', 't'] // test
  9209. ]);
  9210. function getIframeUrl(auth) {
  9211. const config = auth.config;
  9212. _assert(config.authDomain, auth, "auth-domain-config-required" /* AuthErrorCode.MISSING_AUTH_DOMAIN */);
  9213. const url = config.emulator
  9214. ? _emulatorUrl(config, EMULATED_IFRAME_PATH)
  9215. : `https://${auth.config.authDomain}/${IFRAME_PATH}`;
  9216. const params = {
  9217. apiKey: config.apiKey,
  9218. appName: auth.name,
  9219. v: app.SDK_VERSION
  9220. };
  9221. const eid = EID_FROM_APIHOST.get(auth.config.apiHost);
  9222. if (eid) {
  9223. params.eid = eid;
  9224. }
  9225. const frameworks = auth._getFrameworks();
  9226. if (frameworks.length) {
  9227. params.fw = frameworks.join(',');
  9228. }
  9229. return `${url}?${util.querystring(params).slice(1)}`;
  9230. }
  9231. async function _openIframe(auth) {
  9232. const context = await _loadGapi(auth);
  9233. const gapi = _window().gapi;
  9234. _assert(gapi, auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  9235. return context.open({
  9236. where: document.body,
  9237. url: getIframeUrl(auth),
  9238. messageHandlersFilter: gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER,
  9239. attributes: IFRAME_ATTRIBUTES,
  9240. dontclear: true
  9241. }, (iframe) => new Promise(async (resolve, reject) => {
  9242. await iframe.restyle({
  9243. // Prevent iframe from closing on mouse out.
  9244. setHideOnLeave: false
  9245. });
  9246. const networkError = _createError(auth, "network-request-failed" /* AuthErrorCode.NETWORK_REQUEST_FAILED */);
  9247. // Confirm iframe is correctly loaded.
  9248. // To fallback on failure, set a timeout.
  9249. const networkErrorTimer = _window().setTimeout(() => {
  9250. reject(networkError);
  9251. }, PING_TIMEOUT.get());
  9252. // Clear timer and resolve pending iframe ready promise.
  9253. function clearTimerAndResolve() {
  9254. _window().clearTimeout(networkErrorTimer);
  9255. resolve(iframe);
  9256. }
  9257. // This returns an IThenable. However the reject part does not call
  9258. // when the iframe is not loaded.
  9259. iframe.ping(clearTimerAndResolve).then(clearTimerAndResolve, () => {
  9260. reject(networkError);
  9261. });
  9262. }));
  9263. }
  9264. /**
  9265. * @license
  9266. * Copyright 2020 Google LLC.
  9267. *
  9268. * Licensed under the Apache License, Version 2.0 (the "License");
  9269. * you may not use this file except in compliance with the License.
  9270. * You may obtain a copy of the License at
  9271. *
  9272. * http://www.apache.org/licenses/LICENSE-2.0
  9273. *
  9274. * Unless required by applicable law or agreed to in writing, software
  9275. * distributed under the License is distributed on an "AS IS" BASIS,
  9276. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9277. * See the License for the specific language governing permissions and
  9278. * limitations under the License.
  9279. */
  9280. const BASE_POPUP_OPTIONS = {
  9281. location: 'yes',
  9282. resizable: 'yes',
  9283. statusbar: 'yes',
  9284. toolbar: 'no'
  9285. };
  9286. const DEFAULT_WIDTH = 500;
  9287. const DEFAULT_HEIGHT = 600;
  9288. const TARGET_BLANK = '_blank';
  9289. const FIREFOX_EMPTY_URL = 'http://localhost';
  9290. class AuthPopup {
  9291. constructor(window) {
  9292. this.window = window;
  9293. this.associatedEvent = null;
  9294. }
  9295. close() {
  9296. if (this.window) {
  9297. try {
  9298. this.window.close();
  9299. }
  9300. catch (e) { }
  9301. }
  9302. }
  9303. }
  9304. function _open(auth, url, name, width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT) {
  9305. const top = Math.max((window.screen.availHeight - height) / 2, 0).toString();
  9306. const left = Math.max((window.screen.availWidth - width) / 2, 0).toString();
  9307. let target = '';
  9308. const options = Object.assign(Object.assign({}, BASE_POPUP_OPTIONS), { width: width.toString(), height: height.toString(), top,
  9309. left });
  9310. // Chrome iOS 7 and 8 is returning an undefined popup win when target is
  9311. // specified, even though the popup is not necessarily blocked.
  9312. const ua = util.getUA().toLowerCase();
  9313. if (name) {
  9314. target = _isChromeIOS(ua) ? TARGET_BLANK : name;
  9315. }
  9316. if (_isFirefox(ua)) {
  9317. // Firefox complains when invalid URLs are popped out. Hacky way to bypass.
  9318. url = url || FIREFOX_EMPTY_URL;
  9319. // Firefox disables by default scrolling on popup windows, which can create
  9320. // issues when the user has many Google accounts, for instance.
  9321. options.scrollbars = 'yes';
  9322. }
  9323. const optionsString = Object.entries(options).reduce((accum, [key, value]) => `${accum}${key}=${value},`, '');
  9324. if (_isIOSStandalone(ua) && target !== '_self') {
  9325. openAsNewWindowIOS(url || '', target);
  9326. return new AuthPopup(null);
  9327. }
  9328. // about:blank getting sanitized causing browsers like IE/Edge to display
  9329. // brief error message before redirecting to handler.
  9330. const newWin = window.open(url || '', target, optionsString);
  9331. _assert(newWin, auth, "popup-blocked" /* AuthErrorCode.POPUP_BLOCKED */);
  9332. // Flaky on IE edge, encapsulate with a try and catch.
  9333. try {
  9334. newWin.focus();
  9335. }
  9336. catch (e) { }
  9337. return new AuthPopup(newWin);
  9338. }
  9339. function openAsNewWindowIOS(url, target) {
  9340. const el = document.createElement('a');
  9341. el.href = url;
  9342. el.target = target;
  9343. const click = document.createEvent('MouseEvent');
  9344. click.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 1, null);
  9345. el.dispatchEvent(click);
  9346. }
  9347. /**
  9348. * @license
  9349. * Copyright 2021 Google LLC
  9350. *
  9351. * Licensed under the Apache License, Version 2.0 (the "License");
  9352. * you may not use this file except in compliance with the License.
  9353. * You may obtain a copy of the License at
  9354. *
  9355. * http://www.apache.org/licenses/LICENSE-2.0
  9356. *
  9357. * Unless required by applicable law or agreed to in writing, software
  9358. * distributed under the License is distributed on an "AS IS" BASIS,
  9359. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9360. * See the License for the specific language governing permissions and
  9361. * limitations under the License.
  9362. */
  9363. /**
  9364. * URL for Authentication widget which will initiate the OAuth handshake
  9365. *
  9366. * @internal
  9367. */
  9368. const WIDGET_PATH = '__/auth/handler';
  9369. /**
  9370. * URL for emulated environment
  9371. *
  9372. * @internal
  9373. */
  9374. const EMULATOR_WIDGET_PATH = 'emulator/auth/handler';
  9375. /**
  9376. * Fragment name for the App Check token that gets passed to the widget
  9377. *
  9378. * @internal
  9379. */
  9380. const FIREBASE_APP_CHECK_FRAGMENT_ID = encodeURIComponent('fac');
  9381. async function _getRedirectUrl(auth, provider, authType, redirectUrl, eventId, additionalParams) {
  9382. _assert(auth.config.authDomain, auth, "auth-domain-config-required" /* AuthErrorCode.MISSING_AUTH_DOMAIN */);
  9383. _assert(auth.config.apiKey, auth, "invalid-api-key" /* AuthErrorCode.INVALID_API_KEY */);
  9384. const params = {
  9385. apiKey: auth.config.apiKey,
  9386. appName: auth.name,
  9387. authType,
  9388. redirectUrl,
  9389. v: app.SDK_VERSION,
  9390. eventId
  9391. };
  9392. if (provider instanceof FederatedAuthProvider) {
  9393. provider.setDefaultLanguage(auth.languageCode);
  9394. params.providerId = provider.providerId || '';
  9395. if (!util.isEmpty(provider.getCustomParameters())) {
  9396. params.customParameters = JSON.stringify(provider.getCustomParameters());
  9397. }
  9398. // TODO set additionalParams from the provider as well?
  9399. for (const [key, value] of Object.entries(additionalParams || {})) {
  9400. params[key] = value;
  9401. }
  9402. }
  9403. if (provider instanceof BaseOAuthProvider) {
  9404. const scopes = provider.getScopes().filter(scope => scope !== '');
  9405. if (scopes.length > 0) {
  9406. params.scopes = scopes.join(',');
  9407. }
  9408. }
  9409. if (auth.tenantId) {
  9410. params.tid = auth.tenantId;
  9411. }
  9412. // TODO: maybe set eid as endipointId
  9413. // TODO: maybe set fw as Frameworks.join(",")
  9414. const paramsDict = params;
  9415. for (const key of Object.keys(paramsDict)) {
  9416. if (paramsDict[key] === undefined) {
  9417. delete paramsDict[key];
  9418. }
  9419. }
  9420. // Sets the App Check token to pass to the widget
  9421. const appCheckToken = await auth._getAppCheckToken();
  9422. const appCheckTokenFragment = appCheckToken
  9423. ? `#${FIREBASE_APP_CHECK_FRAGMENT_ID}=${encodeURIComponent(appCheckToken)}`
  9424. : '';
  9425. // Start at index 1 to skip the leading '&' in the query string
  9426. return `${getHandlerBase(auth)}?${util.querystring(paramsDict).slice(1)}${appCheckTokenFragment}`;
  9427. }
  9428. function getHandlerBase({ config }) {
  9429. if (!config.emulator) {
  9430. return `https://${config.authDomain}/${WIDGET_PATH}`;
  9431. }
  9432. return _emulatorUrl(config, EMULATOR_WIDGET_PATH);
  9433. }
  9434. /**
  9435. * @license
  9436. * Copyright 2020 Google LLC
  9437. *
  9438. * Licensed under the Apache License, Version 2.0 (the "License");
  9439. * you may not use this file except in compliance with the License.
  9440. * You may obtain a copy of the License at
  9441. *
  9442. * http://www.apache.org/licenses/LICENSE-2.0
  9443. *
  9444. * Unless required by applicable law or agreed to in writing, software
  9445. * distributed under the License is distributed on an "AS IS" BASIS,
  9446. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9447. * See the License for the specific language governing permissions and
  9448. * limitations under the License.
  9449. */
  9450. /**
  9451. * The special web storage event
  9452. *
  9453. */
  9454. const WEB_STORAGE_SUPPORT_KEY = 'webStorageSupport';
  9455. class BrowserPopupRedirectResolver {
  9456. constructor() {
  9457. this.eventManagers = {};
  9458. this.iframes = {};
  9459. this.originValidationPromises = {};
  9460. this._redirectPersistence = browserSessionPersistence;
  9461. this._completeRedirectFn = _getRedirectResult;
  9462. this._overrideRedirectResult = _overrideRedirectResult;
  9463. }
  9464. // Wrapping in async even though we don't await anywhere in order
  9465. // to make sure errors are raised as promise rejections
  9466. async _openPopup(auth, provider, authType, eventId) {
  9467. var _a;
  9468. debugAssert((_a = this.eventManagers[auth._key()]) === null || _a === void 0 ? void 0 : _a.manager, '_initialize() not called before _openPopup()');
  9469. const url = await _getRedirectUrl(auth, provider, authType, _getCurrentUrl(), eventId);
  9470. return _open(auth, url, _generateEventId());
  9471. }
  9472. async _openRedirect(auth, provider, authType, eventId) {
  9473. await this._originValidation(auth);
  9474. const url = await _getRedirectUrl(auth, provider, authType, _getCurrentUrl(), eventId);
  9475. _setWindowLocation(url);
  9476. return new Promise(() => { });
  9477. }
  9478. _initialize(auth) {
  9479. const key = auth._key();
  9480. if (this.eventManagers[key]) {
  9481. const { manager, promise } = this.eventManagers[key];
  9482. if (manager) {
  9483. return Promise.resolve(manager);
  9484. }
  9485. else {
  9486. debugAssert(promise, 'If manager is not set, promise should be');
  9487. return promise;
  9488. }
  9489. }
  9490. const promise = this.initAndGetManager(auth);
  9491. this.eventManagers[key] = { promise };
  9492. // If the promise is rejected, the key should be removed so that the
  9493. // operation can be retried later.
  9494. promise.catch(() => {
  9495. delete this.eventManagers[key];
  9496. });
  9497. return promise;
  9498. }
  9499. async initAndGetManager(auth) {
  9500. const iframe = await _openIframe(auth);
  9501. const manager = new AuthEventManager(auth);
  9502. iframe.register('authEvent', (iframeEvent) => {
  9503. _assert(iframeEvent === null || iframeEvent === void 0 ? void 0 : iframeEvent.authEvent, auth, "invalid-auth-event" /* AuthErrorCode.INVALID_AUTH_EVENT */);
  9504. // TODO: Consider splitting redirect and popup events earlier on
  9505. const handled = manager.onEvent(iframeEvent.authEvent);
  9506. return { status: handled ? "ACK" /* GapiOutcome.ACK */ : "ERROR" /* GapiOutcome.ERROR */ };
  9507. }, gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER);
  9508. this.eventManagers[auth._key()] = { manager };
  9509. this.iframes[auth._key()] = iframe;
  9510. return manager;
  9511. }
  9512. _isIframeWebStorageSupported(auth, cb) {
  9513. const iframe = this.iframes[auth._key()];
  9514. iframe.send(WEB_STORAGE_SUPPORT_KEY, { type: WEB_STORAGE_SUPPORT_KEY }, result => {
  9515. var _a;
  9516. const isSupported = (_a = result === null || result === void 0 ? void 0 : result[0]) === null || _a === void 0 ? void 0 : _a[WEB_STORAGE_SUPPORT_KEY];
  9517. if (isSupported !== undefined) {
  9518. cb(!!isSupported);
  9519. }
  9520. _fail(auth, "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  9521. }, gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER);
  9522. }
  9523. _originValidation(auth) {
  9524. const key = auth._key();
  9525. if (!this.originValidationPromises[key]) {
  9526. this.originValidationPromises[key] = _validateOrigin(auth);
  9527. }
  9528. return this.originValidationPromises[key];
  9529. }
  9530. get _shouldInitProactively() {
  9531. // Mobile browsers and Safari need to optimistically initialize
  9532. return _isMobileBrowser() || _isSafari() || _isIOS();
  9533. }
  9534. }
  9535. /**
  9536. * An implementation of {@link PopupRedirectResolver} suitable for browser
  9537. * based applications.
  9538. *
  9539. * @public
  9540. */
  9541. const browserPopupRedirectResolver = BrowserPopupRedirectResolver;
  9542. class MultiFactorAssertionImpl {
  9543. constructor(factorId) {
  9544. this.factorId = factorId;
  9545. }
  9546. _process(auth, session, displayName) {
  9547. switch (session.type) {
  9548. case "enroll" /* MultiFactorSessionType.ENROLL */:
  9549. return this._finalizeEnroll(auth, session.credential, displayName);
  9550. case "signin" /* MultiFactorSessionType.SIGN_IN */:
  9551. return this._finalizeSignIn(auth, session.credential);
  9552. default:
  9553. return debugFail('unexpected MultiFactorSessionType');
  9554. }
  9555. }
  9556. }
  9557. /**
  9558. * {@inheritdoc PhoneMultiFactorAssertion}
  9559. *
  9560. * @public
  9561. */
  9562. class PhoneMultiFactorAssertionImpl extends MultiFactorAssertionImpl {
  9563. constructor(credential) {
  9564. super("phone" /* FactorId.PHONE */);
  9565. this.credential = credential;
  9566. }
  9567. /** @internal */
  9568. static _fromCredential(credential) {
  9569. return new PhoneMultiFactorAssertionImpl(credential);
  9570. }
  9571. /** @internal */
  9572. _finalizeEnroll(auth, idToken, displayName) {
  9573. return finalizeEnrollPhoneMfa(auth, {
  9574. idToken,
  9575. displayName,
  9576. phoneVerificationInfo: this.credential._makeVerificationRequest()
  9577. });
  9578. }
  9579. /** @internal */
  9580. _finalizeSignIn(auth, mfaPendingCredential) {
  9581. return finalizeSignInPhoneMfa(auth, {
  9582. mfaPendingCredential,
  9583. phoneVerificationInfo: this.credential._makeVerificationRequest()
  9584. });
  9585. }
  9586. }
  9587. /**
  9588. * Provider for generating a {@link PhoneMultiFactorAssertion}.
  9589. *
  9590. * @public
  9591. */
  9592. class PhoneMultiFactorGenerator {
  9593. constructor() { }
  9594. /**
  9595. * Provides a {@link PhoneMultiFactorAssertion} to confirm ownership of the phone second factor.
  9596. *
  9597. * @param phoneAuthCredential - A credential provided by {@link PhoneAuthProvider.credential}.
  9598. * @returns A {@link PhoneMultiFactorAssertion} which can be used with
  9599. * {@link MultiFactorResolver.resolveSignIn}
  9600. */
  9601. static assertion(credential) {
  9602. return PhoneMultiFactorAssertionImpl._fromCredential(credential);
  9603. }
  9604. }
  9605. /**
  9606. * The identifier of the phone second factor: `phone`.
  9607. */
  9608. PhoneMultiFactorGenerator.FACTOR_ID = 'phone';
  9609. /**
  9610. * Provider for generating a {@link TotpMultiFactorAssertion}.
  9611. *
  9612. * @public
  9613. */
  9614. class TotpMultiFactorGenerator {
  9615. /**
  9616. * Provides a {@link TotpMultiFactorAssertion} to confirm ownership of
  9617. * the TOTP (time-based one-time password) second factor.
  9618. * This assertion is used to complete enrollment in TOTP second factor.
  9619. *
  9620. * @param secret A {@link TotpSecret} containing the shared secret key and other TOTP parameters.
  9621. * @param oneTimePassword One-time password from TOTP App.
  9622. * @returns A {@link TotpMultiFactorAssertion} which can be used with
  9623. * {@link MultiFactorUser.enroll}.
  9624. */
  9625. static assertionForEnrollment(secret, oneTimePassword) {
  9626. return TotpMultiFactorAssertionImpl._fromSecret(secret, oneTimePassword);
  9627. }
  9628. /**
  9629. * Provides a {@link TotpMultiFactorAssertion} to confirm ownership of the TOTP second factor.
  9630. * This assertion is used to complete signIn with TOTP as the second factor.
  9631. *
  9632. * @param enrollmentId identifies the enrolled TOTP second factor.
  9633. * @param oneTimePassword One-time password from TOTP App.
  9634. * @returns A {@link TotpMultiFactorAssertion} which can be used with
  9635. * {@link MultiFactorResolver.resolveSignIn}.
  9636. */
  9637. static assertionForSignIn(enrollmentId, oneTimePassword) {
  9638. return TotpMultiFactorAssertionImpl._fromEnrollmentId(enrollmentId, oneTimePassword);
  9639. }
  9640. /**
  9641. * Returns a promise to {@link TotpSecret} which contains the TOTP shared secret key and other parameters.
  9642. * Creates a TOTP secret as part of enrolling a TOTP second factor.
  9643. * Used for generating a QR code URL or inputting into a TOTP app.
  9644. * This method uses the auth instance corresponding to the user in the multiFactorSession.
  9645. *
  9646. * @param session The {@link MultiFactorSession} that the user is part of.
  9647. * @returns A promise to {@link TotpSecret}.
  9648. */
  9649. static async generateSecret(session) {
  9650. const mfaSession = session;
  9651. _assert(typeof mfaSession.auth !== 'undefined', "internal-error" /* AuthErrorCode.INTERNAL_ERROR */);
  9652. const response = await startEnrollTotpMfa(mfaSession.auth, {
  9653. idToken: mfaSession.credential,
  9654. totpEnrollmentInfo: {}
  9655. });
  9656. return TotpSecret._fromStartTotpMfaEnrollmentResponse(response, mfaSession.auth);
  9657. }
  9658. }
  9659. /**
  9660. * The identifier of the TOTP second factor: `totp`.
  9661. */
  9662. TotpMultiFactorGenerator.FACTOR_ID = "totp" /* FactorId.TOTP */;
  9663. class TotpMultiFactorAssertionImpl extends MultiFactorAssertionImpl {
  9664. constructor(otp, enrollmentId, secret) {
  9665. super("totp" /* FactorId.TOTP */);
  9666. this.otp = otp;
  9667. this.enrollmentId = enrollmentId;
  9668. this.secret = secret;
  9669. }
  9670. /** @internal */
  9671. static _fromSecret(secret, otp) {
  9672. return new TotpMultiFactorAssertionImpl(otp, undefined, secret);
  9673. }
  9674. /** @internal */
  9675. static _fromEnrollmentId(enrollmentId, otp) {
  9676. return new TotpMultiFactorAssertionImpl(otp, enrollmentId);
  9677. }
  9678. /** @internal */
  9679. async _finalizeEnroll(auth, idToken, displayName) {
  9680. _assert(typeof this.secret !== 'undefined', auth, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  9681. return finalizeEnrollTotpMfa(auth, {
  9682. idToken,
  9683. displayName,
  9684. totpVerificationInfo: this.secret._makeTotpVerificationInfo(this.otp)
  9685. });
  9686. }
  9687. /** @internal */
  9688. async _finalizeSignIn(auth, mfaPendingCredential) {
  9689. _assert(this.enrollmentId !== undefined && this.otp !== undefined, auth, "argument-error" /* AuthErrorCode.ARGUMENT_ERROR */);
  9690. const totpVerificationInfo = { verificationCode: this.otp };
  9691. return finalizeSignInTotpMfa(auth, {
  9692. mfaPendingCredential,
  9693. mfaEnrollmentId: this.enrollmentId,
  9694. totpVerificationInfo
  9695. });
  9696. }
  9697. }
  9698. /**
  9699. * Provider for generating a {@link TotpMultiFactorAssertion}.
  9700. *
  9701. * Stores the shared secret key and other parameters to generate time-based OTPs.
  9702. * Implements methods to retrieve the shared secret key and generate a QR code URL.
  9703. * @public
  9704. */
  9705. class TotpSecret {
  9706. // The public members are declared outside the constructor so the docs can be generated.
  9707. constructor(secretKey, hashingAlgorithm, codeLength, codeIntervalSeconds, enrollmentCompletionDeadline, sessionInfo, auth) {
  9708. this.sessionInfo = sessionInfo;
  9709. this.auth = auth;
  9710. this.secretKey = secretKey;
  9711. this.hashingAlgorithm = hashingAlgorithm;
  9712. this.codeLength = codeLength;
  9713. this.codeIntervalSeconds = codeIntervalSeconds;
  9714. this.enrollmentCompletionDeadline = enrollmentCompletionDeadline;
  9715. }
  9716. /** @internal */
  9717. static _fromStartTotpMfaEnrollmentResponse(response, auth) {
  9718. return new TotpSecret(response.totpSessionInfo.sharedSecretKey, response.totpSessionInfo.hashingAlgorithm, response.totpSessionInfo.verificationCodeLength, response.totpSessionInfo.periodSec, new Date(response.totpSessionInfo.finalizeEnrollmentTime).toUTCString(), response.totpSessionInfo.sessionInfo, auth);
  9719. }
  9720. /** @internal */
  9721. _makeTotpVerificationInfo(otp) {
  9722. return { sessionInfo: this.sessionInfo, verificationCode: otp };
  9723. }
  9724. /**
  9725. * Returns a QR code URL as described in
  9726. * https://github.com/google/google-authenticator/wiki/Key-Uri-Format
  9727. * This can be displayed to the user as a QR code to be scanned into a TOTP app like Google Authenticator.
  9728. * If the optional parameters are unspecified, an accountName of <userEmail> and issuer of <firebaseAppName> are used.
  9729. *
  9730. * @param accountName the name of the account/app along with a user identifier.
  9731. * @param issuer issuer of the TOTP (likely the app name).
  9732. * @returns A QR code URL string.
  9733. */
  9734. generateQrCodeUrl(accountName, issuer) {
  9735. var _a;
  9736. let useDefaults = false;
  9737. if (_isEmptyString(accountName) || _isEmptyString(issuer)) {
  9738. useDefaults = true;
  9739. }
  9740. if (useDefaults) {
  9741. if (_isEmptyString(accountName)) {
  9742. accountName = ((_a = this.auth.currentUser) === null || _a === void 0 ? void 0 : _a.email) || 'unknownuser';
  9743. }
  9744. if (_isEmptyString(issuer)) {
  9745. issuer = this.auth.name;
  9746. }
  9747. }
  9748. return `otpauth://totp/${issuer}:${accountName}?secret=${this.secretKey}&issuer=${issuer}&algorithm=${this.hashingAlgorithm}&digits=${this.codeLength}`;
  9749. }
  9750. }
  9751. /** @internal */
  9752. function _isEmptyString(input) {
  9753. return typeof input === 'undefined' || (input === null || input === void 0 ? void 0 : input.length) === 0;
  9754. }
  9755. var name = "@firebase/auth";
  9756. var version = "0.23.2";
  9757. /**
  9758. * @license
  9759. * Copyright 2020 Google LLC
  9760. *
  9761. * Licensed under the Apache License, Version 2.0 (the "License");
  9762. * you may not use this file except in compliance with the License.
  9763. * You may obtain a copy of the License at
  9764. *
  9765. * http://www.apache.org/licenses/LICENSE-2.0
  9766. *
  9767. * Unless required by applicable law or agreed to in writing, software
  9768. * distributed under the License is distributed on an "AS IS" BASIS,
  9769. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9770. * See the License for the specific language governing permissions and
  9771. * limitations under the License.
  9772. */
  9773. class AuthInterop {
  9774. constructor(auth) {
  9775. this.auth = auth;
  9776. this.internalListeners = new Map();
  9777. }
  9778. getUid() {
  9779. var _a;
  9780. this.assertAuthConfigured();
  9781. return ((_a = this.auth.currentUser) === null || _a === void 0 ? void 0 : _a.uid) || null;
  9782. }
  9783. async getToken(forceRefresh) {
  9784. this.assertAuthConfigured();
  9785. await this.auth._initializationPromise;
  9786. if (!this.auth.currentUser) {
  9787. return null;
  9788. }
  9789. const accessToken = await this.auth.currentUser.getIdToken(forceRefresh);
  9790. return { accessToken };
  9791. }
  9792. addAuthTokenListener(listener) {
  9793. this.assertAuthConfigured();
  9794. if (this.internalListeners.has(listener)) {
  9795. return;
  9796. }
  9797. const unsubscribe = this.auth.onIdTokenChanged(user => {
  9798. listener((user === null || user === void 0 ? void 0 : user.stsTokenManager.accessToken) || null);
  9799. });
  9800. this.internalListeners.set(listener, unsubscribe);
  9801. this.updateProactiveRefresh();
  9802. }
  9803. removeAuthTokenListener(listener) {
  9804. this.assertAuthConfigured();
  9805. const unsubscribe = this.internalListeners.get(listener);
  9806. if (!unsubscribe) {
  9807. return;
  9808. }
  9809. this.internalListeners.delete(listener);
  9810. unsubscribe();
  9811. this.updateProactiveRefresh();
  9812. }
  9813. assertAuthConfigured() {
  9814. _assert(this.auth._initializationPromise, "dependent-sdk-initialized-before-auth" /* AuthErrorCode.DEPENDENT_SDK_INIT_BEFORE_AUTH */);
  9815. }
  9816. updateProactiveRefresh() {
  9817. if (this.internalListeners.size > 0) {
  9818. this.auth._startProactiveRefresh();
  9819. }
  9820. else {
  9821. this.auth._stopProactiveRefresh();
  9822. }
  9823. }
  9824. }
  9825. /**
  9826. * @license
  9827. * Copyright 2020 Google LLC
  9828. *
  9829. * Licensed under the Apache License, Version 2.0 (the "License");
  9830. * you may not use this file except in compliance with the License.
  9831. * You may obtain a copy of the License at
  9832. *
  9833. * http://www.apache.org/licenses/LICENSE-2.0
  9834. *
  9835. * Unless required by applicable law or agreed to in writing, software
  9836. * distributed under the License is distributed on an "AS IS" BASIS,
  9837. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9838. * See the License for the specific language governing permissions and
  9839. * limitations under the License.
  9840. */
  9841. function getVersionForPlatform(clientPlatform) {
  9842. switch (clientPlatform) {
  9843. case "Node" /* ClientPlatform.NODE */:
  9844. return 'node';
  9845. case "ReactNative" /* ClientPlatform.REACT_NATIVE */:
  9846. return 'rn';
  9847. case "Worker" /* ClientPlatform.WORKER */:
  9848. return 'webworker';
  9849. case "Cordova" /* ClientPlatform.CORDOVA */:
  9850. return 'cordova';
  9851. default:
  9852. return undefined;
  9853. }
  9854. }
  9855. /** @internal */
  9856. function registerAuth(clientPlatform) {
  9857. app._registerComponent(new component.Component("auth" /* _ComponentName.AUTH */, (container, { options: deps }) => {
  9858. const app = container.getProvider('app').getImmediate();
  9859. const heartbeatServiceProvider = container.getProvider('heartbeat');
  9860. const appCheckServiceProvider = container.getProvider('app-check-internal');
  9861. const { apiKey, authDomain } = app.options;
  9862. _assert(apiKey && !apiKey.includes(':'), "invalid-api-key" /* AuthErrorCode.INVALID_API_KEY */, { appName: app.name });
  9863. const config = {
  9864. apiKey,
  9865. authDomain,
  9866. clientPlatform,
  9867. apiHost: "identitytoolkit.googleapis.com" /* DefaultConfig.API_HOST */,
  9868. tokenApiHost: "securetoken.googleapis.com" /* DefaultConfig.TOKEN_API_HOST */,
  9869. apiScheme: "https" /* DefaultConfig.API_SCHEME */,
  9870. sdkClientVersion: _getClientVersion(clientPlatform)
  9871. };
  9872. const authInstance = new AuthImpl(app, heartbeatServiceProvider, appCheckServiceProvider, config);
  9873. _initializeAuthInstance(authInstance, deps);
  9874. return authInstance;
  9875. }, "PUBLIC" /* ComponentType.PUBLIC */)
  9876. /**
  9877. * Auth can only be initialized by explicitly calling getAuth() or initializeAuth()
  9878. * For why we do this, See go/firebase-next-auth-init
  9879. */
  9880. .setInstantiationMode("EXPLICIT" /* InstantiationMode.EXPLICIT */)
  9881. /**
  9882. * Because all firebase products that depend on auth depend on auth-internal directly,
  9883. * we need to initialize auth-internal after auth is initialized to make it available to other firebase products.
  9884. */
  9885. .setInstanceCreatedCallback((container, _instanceIdentifier, _instance) => {
  9886. const authInternalProvider = container.getProvider("auth-internal" /* _ComponentName.AUTH_INTERNAL */);
  9887. authInternalProvider.initialize();
  9888. }));
  9889. app._registerComponent(new component.Component("auth-internal" /* _ComponentName.AUTH_INTERNAL */, container => {
  9890. const auth = _castAuth(container.getProvider("auth" /* _ComponentName.AUTH */).getImmediate());
  9891. return (auth => new AuthInterop(auth))(auth);
  9892. }, "PRIVATE" /* ComponentType.PRIVATE */).setInstantiationMode("EXPLICIT" /* InstantiationMode.EXPLICIT */));
  9893. app.registerVersion(name, version, getVersionForPlatform(clientPlatform));
  9894. // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
  9895. app.registerVersion(name, version, 'cjs2017');
  9896. }
  9897. /**
  9898. * @license
  9899. * Copyright 2021 Google LLC
  9900. *
  9901. * Licensed under the Apache License, Version 2.0 (the "License");
  9902. * you may not use this file except in compliance with the License.
  9903. * You may obtain a copy of the License at
  9904. *
  9905. * http://www.apache.org/licenses/LICENSE-2.0
  9906. *
  9907. * Unless required by applicable law or agreed to in writing, software
  9908. * distributed under the License is distributed on an "AS IS" BASIS,
  9909. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9910. * See the License for the specific language governing permissions and
  9911. * limitations under the License.
  9912. */
  9913. const DEFAULT_ID_TOKEN_MAX_AGE = 5 * 60;
  9914. const authIdTokenMaxAge = util.getExperimentalSetting('authIdTokenMaxAge') || DEFAULT_ID_TOKEN_MAX_AGE;
  9915. let lastPostedIdToken = null;
  9916. const mintCookieFactory = (url) => async (user) => {
  9917. const idTokenResult = user && (await user.getIdTokenResult());
  9918. const idTokenAge = idTokenResult &&
  9919. (new Date().getTime() - Date.parse(idTokenResult.issuedAtTime)) / 1000;
  9920. if (idTokenAge && idTokenAge > authIdTokenMaxAge) {
  9921. return;
  9922. }
  9923. // Specifically trip null => undefined when logged out, to delete any existing cookie
  9924. const idToken = idTokenResult === null || idTokenResult === void 0 ? void 0 : idTokenResult.token;
  9925. if (lastPostedIdToken === idToken) {
  9926. return;
  9927. }
  9928. lastPostedIdToken = idToken;
  9929. await fetch(url, {
  9930. method: idToken ? 'POST' : 'DELETE',
  9931. headers: idToken
  9932. ? {
  9933. 'Authorization': `Bearer ${idToken}`
  9934. }
  9935. : {}
  9936. });
  9937. };
  9938. /**
  9939. * Returns the Auth instance associated with the provided {@link @firebase/app#FirebaseApp}.
  9940. * If no instance exists, initializes an Auth instance with platform-specific default dependencies.
  9941. *
  9942. * @param app - The Firebase App.
  9943. *
  9944. * @public
  9945. */
  9946. function getAuth(app$1 = app.getApp()) {
  9947. const provider = app._getProvider(app$1, 'auth');
  9948. if (provider.isInitialized()) {
  9949. return provider.getImmediate();
  9950. }
  9951. const auth = initializeAuth(app$1, {
  9952. popupRedirectResolver: browserPopupRedirectResolver,
  9953. persistence: [
  9954. indexedDBLocalPersistence,
  9955. browserLocalPersistence,
  9956. browserSessionPersistence
  9957. ]
  9958. });
  9959. const authTokenSyncUrl = util.getExperimentalSetting('authTokenSyncURL');
  9960. if (authTokenSyncUrl) {
  9961. const mintCookie = mintCookieFactory(authTokenSyncUrl);
  9962. beforeAuthStateChanged(auth, mintCookie, () => mintCookie(auth.currentUser));
  9963. onIdTokenChanged(auth, user => mintCookie(user));
  9964. }
  9965. const authEmulatorHost = util.getDefaultEmulatorHost('auth');
  9966. if (authEmulatorHost) {
  9967. connectAuthEmulator(auth, `http://${authEmulatorHost}`);
  9968. }
  9969. return auth;
  9970. }
  9971. registerAuth("Browser" /* ClientPlatform.BROWSER */);
  9972. exports.AUTH_ERROR_CODES_MAP_DO_NOT_USE_INTERNALLY = AUTH_ERROR_CODES_MAP_DO_NOT_USE_INTERNALLY;
  9973. exports.ActionCodeOperation = ActionCodeOperation;
  9974. exports.ActionCodeURL = ActionCodeURL;
  9975. exports.AuthCredential = AuthCredential;
  9976. exports.AuthEventManager = AuthEventManager;
  9977. exports.AuthImpl = AuthImpl;
  9978. exports.AuthPopup = AuthPopup;
  9979. exports.EmailAuthCredential = EmailAuthCredential;
  9980. exports.EmailAuthProvider = EmailAuthProvider;
  9981. exports.FacebookAuthProvider = FacebookAuthProvider;
  9982. exports.FactorId = FactorId;
  9983. exports.FetchProvider = FetchProvider;
  9984. exports.GithubAuthProvider = GithubAuthProvider;
  9985. exports.GoogleAuthProvider = GoogleAuthProvider;
  9986. exports.OAuthCredential = OAuthCredential;
  9987. exports.OAuthProvider = OAuthProvider;
  9988. exports.OperationType = OperationType;
  9989. exports.PhoneAuthCredential = PhoneAuthCredential;
  9990. exports.PhoneAuthProvider = PhoneAuthProvider;
  9991. exports.PhoneMultiFactorGenerator = PhoneMultiFactorGenerator;
  9992. exports.ProviderId = ProviderId;
  9993. exports.RecaptchaVerifier = RecaptchaVerifier;
  9994. exports.SAMLAuthCredential = SAMLAuthCredential;
  9995. exports.SAMLAuthProvider = SAMLAuthProvider;
  9996. exports.SignInMethod = SignInMethod;
  9997. exports.TotpMultiFactorGenerator = TotpMultiFactorGenerator;
  9998. exports.TotpSecret = TotpSecret;
  9999. exports.TwitterAuthProvider = TwitterAuthProvider;
  10000. exports.UserImpl = UserImpl;
  10001. exports._assert = _assert;
  10002. exports._castAuth = _castAuth;
  10003. exports._clearRedirectOutcomes = _clearRedirectOutcomes;
  10004. exports._createError = _createError;
  10005. exports._fail = _fail;
  10006. exports._generateEventId = _generateEventId;
  10007. exports._getClientVersion = _getClientVersion;
  10008. exports._getInstance = _getInstance;
  10009. exports._getProjectConfig = _getProjectConfig;
  10010. exports._getRedirectResult = _getRedirectResult;
  10011. exports._getRedirectUrl = _getRedirectUrl;
  10012. exports._isAndroid = _isAndroid;
  10013. exports._isIOS = _isIOS;
  10014. exports._isIOS7Or8 = _isIOS7Or8;
  10015. exports._overrideRedirectResult = _overrideRedirectResult;
  10016. exports._persistenceKeyName = _persistenceKeyName;
  10017. exports.applyActionCode = applyActionCode;
  10018. exports.beforeAuthStateChanged = beforeAuthStateChanged;
  10019. exports.browserLocalPersistence = browserLocalPersistence;
  10020. exports.browserPopupRedirectResolver = browserPopupRedirectResolver;
  10021. exports.browserSessionPersistence = browserSessionPersistence;
  10022. exports.checkActionCode = checkActionCode;
  10023. exports.confirmPasswordReset = confirmPasswordReset;
  10024. exports.connectAuthEmulator = connectAuthEmulator;
  10025. exports.createUserWithEmailAndPassword = createUserWithEmailAndPassword;
  10026. exports.debugAssert = debugAssert;
  10027. exports.debugErrorMap = debugErrorMap;
  10028. exports.deleteUser = deleteUser;
  10029. exports.fetchSignInMethodsForEmail = fetchSignInMethodsForEmail;
  10030. exports.getAdditionalUserInfo = getAdditionalUserInfo;
  10031. exports.getAuth = getAuth;
  10032. exports.getIdToken = getIdToken;
  10033. exports.getIdTokenResult = getIdTokenResult;
  10034. exports.getMultiFactorResolver = getMultiFactorResolver;
  10035. exports.getRedirectResult = getRedirectResult;
  10036. exports.inMemoryPersistence = inMemoryPersistence;
  10037. exports.indexedDBLocalPersistence = indexedDBLocalPersistence;
  10038. exports.initializeAuth = initializeAuth;
  10039. exports.initializeRecaptchaConfig = initializeRecaptchaConfig;
  10040. exports.isSignInWithEmailLink = isSignInWithEmailLink;
  10041. exports.linkWithCredential = linkWithCredential;
  10042. exports.linkWithPhoneNumber = linkWithPhoneNumber;
  10043. exports.linkWithPopup = linkWithPopup;
  10044. exports.linkWithRedirect = linkWithRedirect;
  10045. exports.multiFactor = multiFactor;
  10046. exports.onAuthStateChanged = onAuthStateChanged;
  10047. exports.onIdTokenChanged = onIdTokenChanged;
  10048. exports.parseActionCodeURL = parseActionCodeURL;
  10049. exports.prodErrorMap = prodErrorMap;
  10050. exports.reauthenticateWithCredential = reauthenticateWithCredential;
  10051. exports.reauthenticateWithPhoneNumber = reauthenticateWithPhoneNumber;
  10052. exports.reauthenticateWithPopup = reauthenticateWithPopup;
  10053. exports.reauthenticateWithRedirect = reauthenticateWithRedirect;
  10054. exports.reload = reload;
  10055. exports.sendEmailVerification = sendEmailVerification;
  10056. exports.sendPasswordResetEmail = sendPasswordResetEmail;
  10057. exports.sendSignInLinkToEmail = sendSignInLinkToEmail;
  10058. exports.setPersistence = setPersistence;
  10059. exports.signInAnonymously = signInAnonymously;
  10060. exports.signInWithCredential = signInWithCredential;
  10061. exports.signInWithCustomToken = signInWithCustomToken;
  10062. exports.signInWithEmailAndPassword = signInWithEmailAndPassword;
  10063. exports.signInWithEmailLink = signInWithEmailLink;
  10064. exports.signInWithPhoneNumber = signInWithPhoneNumber;
  10065. exports.signInWithPopup = signInWithPopup;
  10066. exports.signInWithRedirect = signInWithRedirect;
  10067. exports.signOut = signOut;
  10068. exports.unlink = unlink;
  10069. exports.updateCurrentUser = updateCurrentUser;
  10070. exports.updateEmail = updateEmail;
  10071. exports.updatePassword = updatePassword;
  10072. exports.updatePhoneNumber = updatePhoneNumber;
  10073. exports.updateProfile = updateProfile;
  10074. exports.useDeviceLanguage = useDeviceLanguage;
  10075. exports.verifyBeforeUpdateEmail = verifyBeforeUpdateEmail;
  10076. exports.verifyPasswordResetCode = verifyPasswordResetCode;
  10077. //# sourceMappingURL=index-5ca0aadd.js.map