From 045ba9195c4a5b7686a6406b19a9e6614ea7ac72 Mon Sep 17 00:00:00 2001 From: Pedro Ferreira <10789765+apedroferreira@users.noreply.github.com> Date: Thu, 22 Feb 2024 11:07:34 +0000 Subject: [PATCH] Sort out rebasing --- docs/data/pages.ts | 4 -- docs/data/toolpad/concepts/authentication.md | 11 +++- docs/data/toolpad/how-to-guides/basic-auth.md | 16 ----- .../concepts/authorization/credentials.png | Bin 0 -> 23180 bytes .../toolpad-app/src/runtime/SignInPage.tsx | 6 +- packages/toolpad-app/src/server/auth.ts | 51 ++++++++++------ packages/toolpad-app/src/server/basicAuth.ts | 29 --------- packages/toolpad-app/src/server/config.ts | 27 +-------- .../src/server/toolpadAppServer.ts | 10 ---- .../AppEditor/AppAuthorizationEditor.tsx | 9 +++ test/integration/auth/basic.spec.ts | 40 +++++++++++++ test/integration/auth/domain.spec.ts | 2 +- .../toolpad => auth/fixture-basic}/.gitignore | 0 .../auth/fixture-basic/application.yml | 5 ++ .../fixture-basic/pages/mypage}/page.yml | 2 +- .../fixture-basic}/resources/functions.ts | 0 test/integration/basic-auth/prod.spec.ts | 55 ------------------ 17 files changed, 105 insertions(+), 162 deletions(-) delete mode 100644 docs/data/toolpad/how-to-guides/basic-auth.md create mode 100644 docs/public/static/toolpad/docs/concepts/authorization/credentials.png delete mode 100644 packages/toolpad-app/src/server/basicAuth.ts create mode 100644 test/integration/auth/basic.spec.ts rename test/integration/{basic-auth/fixture/toolpad => auth/fixture-basic}/.gitignore (100%) create mode 100644 test/integration/auth/fixture-basic/application.yml rename test/integration/{basic-auth/fixture/toolpad/pages/page1 => auth/fixture-basic/pages/mypage}/page.yml (95%) rename test/integration/{basic-auth/fixture/toolpad => auth/fixture-basic}/resources/functions.ts (100%) delete mode 100644 test/integration/basic-auth/prod.spec.ts diff --git a/docs/data/pages.ts b/docs/data/pages.ts index c80aafc1bf..ff6f502445 100644 --- a/docs/data/pages.ts +++ b/docs/data/pages.ts @@ -164,10 +164,6 @@ const pages: MuiPage[] = [ pathname: '/toolpad/how-to-guides/embed-pages', title: 'Embedding Toolpad pages', }, - { - pathname: '/toolpad/how-to-guides/basic-auth', - title: 'Enable basic auth', - }, { pathname: '/toolpad/how-to-guides/editor-path', title: 'Troubleshoot missing editor', diff --git a/docs/data/toolpad/concepts/authentication.md b/docs/data/toolpad/concepts/authentication.md index c579763f25..793b29f799 100644 --- a/docs/data/toolpad/concepts/authentication.md +++ b/docs/data/toolpad/concepts/authentication.md @@ -28,7 +28,7 @@ Please make sure to keep this secret safe and do not share it with anyone! ## Authentication providers -In the authentication settings, you can set up one or more authentication providers for users to be able to sign in with, such as GitHub and Google. +In the authentication settings, you can set up one or more authentication providers for users to be able to sign in with, such as GitHub and Google, or a username/password combination. If any authentication providers are set, only authenticated users are able to access your Toolpad application. @@ -88,6 +88,15 @@ Follow these steps to configure your Azure AD client and get the necessary envir With the Azure AD provider, only existing users of your Azure AD application will be able to sign in. +### Credentials (username and password) + +| Variable | Description | +| :---------------------- | :--------------------------------- | +| `TOOLPAD_AUTH_USERNAME` | Username to be entered to sign in. | +| `TOOLPAD_AUTH_PASSWORD` | Password to be entered to sign in. | + +{{"component": "modules/components/DocsImage.tsx", "src": "/static/toolpad/docs/concepts/authorization/credentials.png", "alt": "Credentials authentication", "caption": "Credentials authentication", "aspectRatio": 6 }} + ## Restricted domains In the authentication settings, you can specify one or more domains (such as `mui.com`) to restrict user authentication based on the signed-in user's email address. diff --git a/docs/data/toolpad/how-to-guides/basic-auth.md b/docs/data/toolpad/how-to-guides/basic-auth.md deleted file mode 100644 index f397858f29..0000000000 --- a/docs/data/toolpad/how-to-guides/basic-auth.md +++ /dev/null @@ -1,16 +0,0 @@ -# Enable basic authentication - -

Add basic authentication to your Toolpad application.

- -You can integrate [basic auth](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#basic_authentication_scheme) into your Toolpad applications using a simple environment variable configuration - -{{"component": "modules/components/DocsImage.tsx", "src": "/static/toolpad/docs/how-to-guides/basic-auth/basic-auth.png", "alt": "Basic auth", "caption": "Basic auth in Toolpad", "indent": 1}} - -## Environment variables - -Toolpad supports the following environment variables to configure applications: - -| Variable | Description | -| :---------------------------- | :------------------------------- | -| `TOOLPAD_BASIC_AUTH_USER` | This variable sets the user name | -| `TOOLPAD_BASIC_AUTH_PASSWORD` | This variable sets the password | diff --git a/docs/public/static/toolpad/docs/concepts/authorization/credentials.png b/docs/public/static/toolpad/docs/concepts/authorization/credentials.png new file mode 100644 index 0000000000000000000000000000000000000000..aa84a629126192fb836fa42f64e3a59c6ddd2d6c GIT binary patch literal 23180 zcmb5WbwHF&*EqZgih&3iAhEQdA|N8UNGL9$5&{B}64FSsfd5+}PM)WMtgh+V=DF z`}pzW^78VJA3xr{eXFOZck|{=Lqo%%p&@5yXCxBY-rinQQ)6Xim7Sd(A0NN4us|QO zYF)JD>gw9u++0vl;N|5dBqSs$DJd%}%gV}{)N@!|Tue_-52s<};o*siiK(lrqobo! zP*9kgn{z7LvbVSYl$qJp)wR63VPay^(b4hY!v`fLrO?n&TU%Q*GxPEBaTOI6A0MB! zjVz!Rj_rN<@+BxJ=*^oqA3JtaQ&Vr> zzMcPL@AJ@ZYinyoMTJ1@x`TtGhK5FRaQVY=(!2OC=omeBIT{+UcEIFDfdMPu+Nc-EjT9 zyR>`G<+Hk!-e?UnD-u{s?P91-(w8#7Vb%gKlN1|?=-_Phm!kR&8|z^nufH@zvfGbWc<&Ri^UxyFQ|<;M*6=2{`F94whfWY z!?wDoNQ)d~x@aD#2F^VcNz?jwRq*bIi1|Yo@Q$wC_}^%T&a%O01XWL0?-X2FFm_3I zjXe$f2fCneIP3qxcfO5_#4wmp^&et@7BE;%3)Oe7@^HgqD*x}JM`G{e;@om z*z5nncUp_S`T#VM8<@f`0%y|C5yH@M|6`&dBz`5AF^F}B|Bc~M;eywnnbDZ*J7VRx zfR#gENr|K#p$vzH_g7*d{v)nJBxZj&_ILqQ_c*hHS0L9wbyU(20b+~|is`AcT>T5; zufIyO-lJ*$kCHLg_AioU9~0GTi-De!e{sei<`tv+!?I|GV`>L<`@c@=yJ&u9APhn@ zT@`t+OzDko;a!Ho=>DgE`QP}C`8dsfQTuN_H#?+USU{YA(hyvV6aU$ccgjjiYRD6 z9gE^IJ)Ru`G5x1kV6dd8{hd&QejWQ6O#3383ZX)OUd5W_7Vrk6a6T7o~ z6q~19Tx$AeNPM>NddKANmoJh;3YzMM*xv~%GPB&qNl_F6C@p-Eo~V&A#$sTFpPezV zx-nfUpV5(28ETwY!H5$y;eA%QTdfbN0ScQxvvRB3#ssc?bp-wtO`f~ebIQjt1DoJw z#V`e1i~)WLI#(gxj1whLQ=bZmBWBRURns>1ZF4uwDEcKVcEX$rCXNUy)a_@P=v{xm zVJ7QP0NO+;G)o~%4#vo8fF46vyBW{6w>>{({9+5F&ab=Jae9gcqw)!Nn5_f}8_P6` zPUF8g6avbGxDw{WY@BanBmlAenzCtqV+i+6e{P>fOA>VB_=$M_*y6CCPQDTYL=gSa zEinPBy!WaU@NAt9Rq%z41+s)-=65HS(0dnamaN&&)t{X+{-~Cez!Uuyo#>BOBZBvN zK7!b_saed#pN_QL^kOLPA@3$vi6tjB=3O_=t4d(B84IUg%s6kT4*1)4ph`hE0lBxW z3hGPKB1!FkfYn|s<+Iy)YJ_PYONvp%HCJI_KMM)bs|8ap42o9UUt&;6FQf{R0k=rB z)pYEy^l6z)GhfbtsKBAxT8(Y93x38YA=(3Ru~$cP4Ytkxy$qj(V|97P2{biu(xXZm zx9H(MCMydw?Y3ht6+wqW^Y54Sa#a~^tdNdwD?md?$In*Ta^7BR#+0`Ze{cW_=hE~H zJDf2lQsz)?($@R5AT+s*GlZiu1|{3KsC4dPjP3xG7>hlMY=e}$QEt0p;a32sG-TF! zA*HNBLK8hZ;=nue=ke*0wr_L&4;42~X@mgg;jx%c8EMPBx=GQs{_@d&8Z0&ycuFlp zAhUU~LhQoNQF?&k1JtsfeXeD04l4aCeL2uem%n~shE;tDxY<(v=7Ra`^*Li%Hlvbi zkuVW5<7(H_IV?tuTN#nFb*uqlc)DlV9Mpry&O7l;f{|peUq#8al4qS2h78K~jxAh% z{Npme3e`9mxL*RQjUx;>UsSwus}6KbV@kiO_bTHF9Oqjr@Ezc4NO=10N-`BPk`E8^ z(zO>;^eDoSNwc>XpCc<=PXh3qw|;bCSEi!!eF>ev2*DpS0lM&R$y)LdOt$elvf9uR zjQjt51dnS$}%2rOEJ0^`YDvKI1ot)8HI4=%LPsjWyu*At+`RT7$4Qsj;JvXT$m~( z2d{OW!5Lda&y)-tB2u+Rw8QU-ekuGIA zl^+w(eLo`eW`ULb*EKm;_8?@%M?kuIU<f05qamB z%nHXnC2H^Z+nBj7FqGaIHiH#rlqyDW-YcFLlgg8mxdTY1ts@(WtT))%Qp;_?GTF?+ zl79k^$eca76|1duDSc&%i1d^IB<4Yz_1JmD7fnb-y{xhyYwJTek!=7798U+MkdZg& z2q10Hf8MkitN(xuVjC*7C@bbNs6}+d+bsnQ~^p+^-8GjA)qubvH_)#>57jzg(hE}F{$%8H&4dHx)SZWP| z4<08x&4LS~p6eHus1hP`)BLc9XYR%;wPArvsv6QlY{^uZ+344IBaR`6A)P{>qt(Kj zdv*N%C{VJI92+tSwn-W48Q@yvvHMRRxV0`j==I?gW z5Ia*^s@B0c=#vKmCp7E{c^_8kL?A=AM&bb9N&CpXuyojM#%@0Scyk&swZ^j_lo$7H z;L+}dw7c`C(U)tiU`BE`%$mPL@Dr}ps$b#;ixTue1nb<~49u1Vl<(zmg%;i?225AE za5u%9qF7r2C~dh9&8jRj2uhq+Y@>Xzjac!bn|Jib1_08@-#$FPZX;+ek=|+zCJ#!L z_t{^7KeW`w0FkV`_sf$MV})%p#H0p275N- z11|CWCp`7YoBtpJ8dN?wwg@M0Jt|vrr&0jWz(G6>8@oXfD7WX#mjT1vf^5YmUM0u zeUBZj4T~GBmu_2J0);k_j=k60r3W@bQ^;QM>o`5Ubt}F}8HTR1g7xbhJi9aSbJLt) zCjJqVfjA_A^knMB@%Fib59)iw8#rsRzGDz04NS`xtJ^S{d#8-aclbjN-VOenvW$~~ zZKkZj9jmMKC_FUq2;}l|f^XRIU)d+W{@q7808(qBH}B8t6@F@4MCcG=LymwoV~A&x z*K9ZKxbhTzf7N32ZszoQ!MJ0Da9i+$nlZZTb27D#eDZAlYRo+^^-!Q5GFM(w`qHB# z1D#Df(=)S^lA`3_e4Wak6t^j1ilNRbtGF<}&(y2aH{Xsv5A_dU%u_DgPG*A)id?2* ze80FMf@3H|wtmxA1t0>%EA~xU(9I02QFcFapjeFqzyQVxzCbsg@#34#o$-uO8Gj_q zxu>Y4EAaz6dh~+Sso>lE4t*aJl%JJk$bU8&aHE}Z5l^ya^HXd3e97*%f{yg5YzouT zKIGEq&O=(JYpa&crz8(58eOV*i_Yx*{0ZjcoWR|WVnL(^cFfPt9&JbsANqFYGRQzTm>7$!{URH@AOkBX1G9sMd!U9Qsd9PYSqj(oUPs?l^d7#%}ktnj8` zrM9a(_!+shJx910{4qtOaRYVH+lNxP3Vq+f#KLISbvttz{bvkP8`LqKuhb9nGSf7_ z25J#szlzbG@;_A;q@E}tdfss05gn$1e2sOX(u9c(hMxO5!3V30@FFKGu9U8(IIuW;X|M$yz{}>*3+@q=O~W48V~7YXR>BlO`bE%9kJ=nugA91 z@snc(!e7Brbe)B`p9YBlMzHA(vGWT~0Vuh3&L?KC3<8mhI!G-mk``=6(-wKsbFhH{ zgQeuhCl1P(qc}(P5e0gING3*sst4Jqcpdf8^xLlqVMdF;rdg0$Kh{P{MUR;)B@@KVUA_i<513HIylAdOQiKrv{MyKB zvUNBr-uncs?h-RA!8qp>$f<<~6TyBobaAv4&??wl0fs+!g%RZ6^?+;iZxM#KH|u>aLv zZQgAJ-+otrgFuhsURQhOBh|rmUGhdjB_4ISV~5|u^OsvKSJxiaW2=%l)^u-` zn%ww_SlQ5-+S&DrkT~jXAR~S1s&Ya%cG7<|t^TH@kW(`srg)a5PH;ZFpx2=R*B zTK1e~?YrFtC!;1|?~0F7T**b!^yf@C zFpagm!Siwb`iFcdP6|({bh?74Y#8{Z@NhB8^LH=`Uj2(=2o_+J+Pa-DkMp^28cw!3 z#b5D`oRCSYqeQ+i4MTB08+$_6#tQ1({>DfBpa@fIwK|2`(7IiU`0=iKdVZn}<3NN5 z)2a?PK$~?9&OAtIDTqMjl6WoxTUOwOyR7_h5`BP0ELf+0nS9f;;t#7MHpPsj+8s2P}PlvE*F4;;|cQ5LZi3v}NltNI_B)^Q5u_&SeatraGzW`jb0wzIIWTG;L)!{ZgiWYEW6cenu9|fT98PaM%U%>>HB>* z(dLp^)#K-=6_oufD+NKa%BC&~*0oD*^X<3RhtEG;Fz3~YQFjG2onYz4c@!4SthXN{ zagvEb=GD^(WD1W(UdT?V1L+ZJ!Qr*cd|SDGJDh^n*jVnTF-WA$w}oBu@{(WW;qRB_ z442ofUQT~CvY2h2AJIfCGX_t#ZJJ!7RPVo=C|m4oZ+V#(14|Zcw1QonbbM!ERW1Tg zaDR=RU*9@H@2=$`8GZ3%`4v4)wo^wYR`u@l+X4IG5~!d=FtpKTbE-_h{olpK)5ScpB_QMUD`o}dp8$T_2&4?xfFHn}l)r$7DaLH*F zJkwILHQc@4%QD-|^{4EXm$wnlBTMFlQC%YnPulyVJjGFRYnrz5FFS3H=0LV@hzYN~ zuY@>oHF>H@7?zl4`xe zzh6`9G_woifigKah!2eKd~VoDejJ$2C^#YDPU*VmnH7`q z@^cvsoei9U{`h9fk2Pd@qbyS`z%mHAmKkbuRn+L;k{?iua0>z)((Is!M7#_efCY$Yl&}HIPPq-v!NjS)!8|tD`V3$)L=$< z3j<@OUp<4S;P_sDUBHeED$NUdYVZ-Pql8=?m0G9QAkghkD0qGH(C_E^%Fe#lgq<8N z;7(u(5Pp%#?7bq$%yK1w;MCQ+Tg;K?UiIppX-v9TK3U{>C&~iWUcY%7T|HN@jO~?K z1F#QG`8=rmB>*jGa96wy9I#!V@L^)N&f&vItOkunZGOg54&~2F4G;b*LL<chuxx)tlH3ig&Ur~)N4wbsI~r@wx;An`h$Dx;6K-_gP_ zu>H=BcP8DN5$M+6DHHO>hoLF|cZ${jm&bqX%#Q5nu#EfO& zDsc-oSlcEWwspOK59i*%XKQoS%?axqXE}Alo7)0C2xTe4_bXHM=SVr0KdHS$^x7if z>ji|;&fOL$PAk4Wo>MTiX0ez_%}k4fxeA+sDZF#!6Zua>YL+12Y~u|Zw(ykl;QgrR z4sYcsq&$5zFh~8_Ha2XJUCm&%&JIkE7*u;3?fAl?9Q zjPnegA5rOai!;qs>*MzpEkB;rHphC$4Nb;{W;wOyBvDjQwTkaA4how+V5Ry@dgh&O z&h4Un+mZ6EnryRaw(aHBVFbDOc}a|WO8f)+U9+u%73OfC3lV#~Ru6 ztGNb*MB>AQ+OjOev9?z?Q2Q;9w;SXQU*?tN+IjoTLNUkB(X< zp6l&lSF>a>chE{vx#ODeaBIrbnJ~ITJcUJ`VR(cy^6W@zMk7@E=^!RIZ0IA3z}Jjg zTzd$KjNs2HOc`ON#!axp<1oY?FN86zosy7Z7LX<;Q;ZUzfh89HKV5abBSuA;e^?S?}f4cGy zF$g~AH%45Rwbd|xWWsf~8?`mAhlk~E?Hpe60%&SJ#TAZFfwM|-8mk0dJ^`t{yZ z9PD}BUss8E(;wP3_vo@ghCPo{rkcx$&lE!0TJK3&WQ^k}{#81BR}tccD`(m4R!%oH z&COlJhkNIpNX*XM{rbApvd?AZr?3G6e_gR7;JfP=;~ut4vTB2cCi`QtvTn+2W1Ku= zS1#NO(wKgt=PnHYDv@cC9reDhvRFmzmW;97y+H~7!uxdG=UkQ8T}6JHOZ5^wx?C=3 zcgl*5i>huuuf;dja$H95QI|sM5g*<~NZ`tEUYvrU#NQJqB~=I>p_6J)vW0A=vwB2sb-x z*E8lmJUf{;4a11k+VL-{mCcQ=?xK34lWh@)WXrZxH=YgJKj77WZs2Jk!AkI1zx^Oi zLcBOWb*?9yeDL*jGGo;yyr}hUZ8(@jT&cHs5$ERF>#%2o=CVBrS`3N9-<&Vv#IOBe z@9^Soa!)9E<}9*iIa5V(a>gFB@xiIqiSRA|fFOossVQVWLz3Tmd;7=1c-HOvx(5yR z80LW`(&)1*%r8_bMxVUpXC0k&bl4UAlw94~zzkMDXP~u5ywf)`RS4Il4Ia4d^h|u@S39_Oe1;R?6z@t6$ zPPEc9CH>^NqJkDz_eb(a-$}O3F%6Zd+SoM1zu4f1;H;J?>?rj{J{DBk_|$~uC-kkD z;py0!Y%`b)Ceaqvrr4<7f%QEb_aEX5aCs>V7kxKt)30A~Za&F;0i}g0#eElDmC6iB z(Dii;Y9QY6tP`{LPsFw8cZyU&$kyto?jee;KiP}reTU0bydFOxyx@?zdCooCMk*!2e<~m3ToL(v%XhTM>=?S>N4+J);=vS1my?q;2Y^J+(3TP}WHU zepf@-;d0n)Ao6q0GDmH&{b%H2*IpSAkCK(b`>5P=H_NoBzZ4zKObYefz>wrqP0HG3 zw)f|`s(pJgo%+rB6FJ^9g?zOBfk)xD8(NVg7Nkn#y9w!T(Z(%wdt}@NJdXKezeE5ari^`dL zBV1;a5|e!nl=hQy4ftjBeNVey9A)cXD|}t}fM~UE9UuE$28?COtz`k+@|gF?Y(DPF ztQPySDH!oI@oF63=b zh!~`c%evTt#f_yY7u8r@obZnb%X;nl6D5ayDZ5x$A@T9#z)ZqwU6jLTgmTxtGdXSj zBsydMY8~Q|J(9z(^x%#sL+&pM{GbRyrgog1bEy*;z1ru2()PWB;lGD*I>EbIhEyc| zyBm^kL_-vd+@)nF8ba%^+!LQ(=TIiyNR4A7sK**yF=mtNV(g;)=H35kHh{E+J{n;M zAGgXbwzn<(w4TgXJt0G?=$|Q|p%1$K#TW>zjd+lZW@ywZNT;F6Hq0frudhqbT))s7f-TFo2T!}dAHSreCB^kLC z{V{*m^#=}D_vyV0^krP{tm+w}CvM8%S8|_G;#a*jJMQn(RVLWo>RmTC-Ory!KjF{2 z&_BuwqkeLj7F3!QIb!x&fR-+fxqQ>ZLyy2^MQnDWFC_ol{;*p2x@q6VO`J8>Fr=N< zCwX}a+w_3N$`(A;w(}W3Zm*uUN)Lv;2-asRCD z(8@X0=r&96i3B zgh-)oYVQl5uNIVr-AZtUh^^<~vMTnrQcbb3sRXTh9{!a;ZEkUboQx53ZKg7iYO?C# zMW-|)*!(2Qa9Nl*T8DR;=oP7<0w+fLFydn=>#5iDjo2eR>c|VUs$p6h9&oX+Lnycl>SaoI(K8>pKHD zgVZ`vwNmKWGm9TCbZthJH5>6@-jyZx32EKS$=8^@_hkY-|FWz~gvtp%9$7i(HSVAf z%LwT)j9tB^FK^ygNxJO1X=M!$A8ip>IDsxGx@=f zAhq>)OteLx-y*Zz_9Y25QgDKux*qF98p9;-9IUkEDIWZVE$w=70BwN!**uVL$hv&*Wn2 z7Hbf)Mvd`1dU4;_Gc)4za*rBZyqr+IZ)IXEd&x3{foQNh9EcwOVc|I;!E<*DuQ|bs zxDc)`f^c41NCe3#B9OG*a2=eUB8ric=XEETt|>^_hGIYN%SjuOvv*cn#ugFsC7EDg5Y({;!m_F?RWf(h3kcs1t+x!BBH)!rETKFX1KrR1Q~xi zb3|~ml6J`uS(1PV30)G7?3pzu1D29x2M#uTm)Y?Z<~+HA!E)=Ef4< zu=qrkxGJ;0$~r6~-BmrZiOKY8pJGaS%mRl}Uw~h|a%+!FznY*_H;ZSW^^LTNYlhzy zv;#fcGoD_4o5l8)*QCx2|1NKDj!c66GCv35eM}JPwQ_kT(L5AetGZLy8Fq zJ&;yCJf_UIilF?%Yap{tEbQo+^{)#4Kbpr^NNxu=Ql0+Q;P~&p?xZht&`0FfTrsm> zM&viee6*IF`&S6kvt#k5M8{$RPalhCJbr)%gT?$=e6I&YyWrv+g9gK)}1*13Vu5t`SyQ95O%x?=nfp>#eyvXx7Q$i z_^m*rxR?q-*OlXFp#6>leG!xY2|=xY1^Rl;{i#LJYE_#-6$v{nDoo_iJtms3tzGrP zfYr-6(Hjar_?6HU7F3moxnPH)lCupghGE|yP~%iGh0VeSJ5}<*)`nsvAK0w0E%xuB+&! z4^w+f`^?j!VJgV43o|MeKI(jn*1Kf3wk;RyT6S+_3`T}_ndKR~S7ikmO`Gc-4> z6=7Y}4v5Q`Vm(SYCMVh-wviY5kT5s+F^C7mUkz77`U@#s5`9SjDQ=bL;9KL#x+m*Q zueQj>+bVFi7iq-<7{u?icemvteyHDkdB$j$vO$jpyV^x{`M?tG5Qb!Xsfcg~kQkcl zVto@QW#ss6eIn@{L}VWt=Am<)zZm!-?=Epe74#oIwBi)NjNn=IkG(R=czig0FE|yC zYZD>yy7m_?+p@^-t5fFhPbmw_n$TdnP?_IYRaqBNmPR%#5FYIg?`HMv;PUnwm(wrJ zFq7{45U6RzHe#(#kX}d+1buKaId8RLP(exh$}jzlvFp-8ckWrq$l*kquIQD#HM$(Y zP=5#)KkO|j>EwLF4y#)Ixj$8Qx-*axPi4v0)8m1jkPi_%&3W50s#?{OAn8oFrDP2L zp5`+FXR`^4DU5i(KhkHJ^KPn#sA?j66aMvGo}_O~s9Zkh#z&?wa3twyZVJEL=Wcns z*ywKRYT1kwN-oL>I@R78i}`BR_*p~x8Fuz;aW|Lu!)BI}oz<^ay|jYXKyYJ`3*^nx zAN%qwF~n8-T3iN`C^ov7dyQB}yZTl_h`a2@7d{W}de}7+V>>(*MBSE_~n4 zWdsFLkD;guq1!S@*tc_6jv_FZ0?YVmKxHA=+F>4YO;lP=9;8llRp{?`va&zQ{r&on z|9t^)hlLyietxI3zoLz+*xw1x?zhR|arx%{l7Cp`*gpeGw~j{}AHTbB>~h61O*hCj2#@cmdKeC)_0wIk23gIx`-UeCk_5w3PR+ zom6lffOf405n{uFU_Tqi0-dQ0)*Hc9*Wbpf=XiFuh`tKV%8F!v^l{)+jH>&y>Cx{K zx-~C6XJuXyUuo(+XOYq(x~@5ZsJNYcZ|s(J&U539*_&Wz8k}q!UBf(-O<`CU;0}_! zAu6kd&`yvJcu95l#AU{TzMg~hOX8^|A5vu6sJ!fK%ncc@cDK>oONh7&wN+GMTb(MA z;8zcv6y2x1P?T&Nohc&f6ouSbXBuA-E0_;9PgeNR#AQ`%(yMj(*(jnNW3-c*_QK3| z>@uBkcyGgNK7D>Z=_&}8hFMt?)|c-JTcp|UyZ%?7GA37&O#<&Xmr63F7=;kL8MIxZ zi>?K#N6Tuzr2cjI`GHPdo$D{5rkR;)6Kxr%&UEursMkh@oaM@A(@}*dB%v(zpFF*4 z-|Z&*hgpP%={Tu2LPpnz#yQP03dU!WToT-Am5Iw=OkwK(m; z+p$fhhz4WH^oiJnMqZRm)ojNZl__I z+Y0MD|iAH8~IR&*Ndx6yxhCyhScnM zui1Bd!O3hjmKCj!^OucB+wQ|f)58idNO`py)Hr*s1N3NCvLN@i1;nRv z-5;ffj>$82`#FU8h32DL)9Be<@rI#Riy~*C|s^$A2tHcK%J~%X){yJDP`fUT~ zhG@>do!G->#OiPnUyJ_LJk9;_g=hO&CKaN=ft~dZ5f_Y0kY5q2X7}nx9SkTiBgl!* z;(2vXTfbP>CPx8PY$>I5B}>$-q^U{NipppI)3fj*@@i$Xr-$5*5qX0GUTr$MtQ7+j zaaIT~@7*SZohjcBT2ZA_utW1g!dT$PXOI50BBoH!sEz#Es>zl=b76CoasOwZMiLni z*C__k5WgGX>`_}^?6OcOj|zU~hq{#=ad7+-9bZQx3;OqBIiGT3io|^u#&t{lG`RNFPZig9Y8*^^J&=|*E8~vMSM|t*Eto4#EU3Z~u7m^TuE6aR~_|jMLYUhm62vsF&h@H&*~FcELn~P&kJC{-%7-R(V|o7`z>Sq~WBCcX zt@KL(e+DCFRF&SX0^0jp&{1`A7mK@*jY`M~DC)>6V%)E+MTHQU@=vxZ_|iT~guQLc zH8eutOiDT_oUqq)7Y9;}5?8Zb0ARGugymTs!NV7SNGgEF*;pCE3dgtjadw>rGx6Z6>_^H;7&O31}91wJ`v}xhq(!IBD z9kfk8){?juAuXccDz-=`R-^jv7w* z|5a&oZh+SJi}WS8wopS|4ihf+7ne@q(9&vX;D}v1b@C0BpGFUFJmYm?8h9dUi~rQk z1Gekwh&T|o5U>Q~(SF6FJP--HFh(pyxZ*(pj%O>A0+G28O4Oh3Ve*N!P%gl*3>(W$ z$m}+za31`^V{c|vkJ@bS#xrc*5gLB#j`00QbRm(SHSeB>TG-Y^&ce(=$S6l7a#kG< zj=W)YpExk&Sgi*v*Cs#wYBXec-+HTLmz4&T+Ty#he3i%19s!I>bwA|50)X5B3ZMJ z<987>2A9;~EDL-lA{X{cLb#D7&nPlsC1D3QmAe`r;V6Yw+TV2;lZ=COgu5I-gs$3dM{Er3o^4A6u*oAQ@N0kthh=7}pG`;YGfJ%JAStx(2+CV2uv z8up|TpN71k?gp%@{DT))qPZV9RQvB#a1s=JVZ-(2R6-Z-_+b35gW!*=MOI2@n~iPp zU_#HHO+=hp587%9MxBH$YZnp5V*I6R=Kv43O!S;#+{jEjvjjqs^`WIJ8eA#T7Q{PR zU_$m1L;w$f-u_F{7&*Gw=Ls#b{+%q3?pF=>6us?A{0uxPXEEXHEe6i*r<5kIw0~>9 zLT_5-@Rn&T*LREd-iI)3vY}S~3Ej!v z6!008GM~fw<#&??r|Y0MjWkp-w~5uq2SDbQxO-IaVf>#1wcRJ=hMojsh5Mpv zhMD!#H&;4Q8~x_gIl(2&je9Se66;k9bX}{Arfjgn<#twPqywx_TmuaD9GqQ*%2s`} zVS3C^meoHhCc&6~i#u@Ff9q?uPEof+n&>%w6@(sZ!s|E1lY>`8{Vff;$Rst(>5c|w zRKkI|$DACI$7$T-{ozfLE|+Y_Mnrc;WW?*it}eSK*z zeAcLVamQYE(+{FmhH$ZSxGBpISAAoK;uMhzs1O!@RlQ_*KG`r5g%}0zmks$O+u5yjeQpUsB*w6)s&> z$|zR9wZo)$rF(HPviG%GWb~}9`H0e8g7;zR9eHoK6_OBMn(?ei=t2an=Z4d*j3B2L zto`TYmo4U<%@bOoNVC|3RLvG_d3)RH%L&Sv4kPk=6v@Vtc}+$c;k*{np}d@(AjtfKl5WR~F+j|3;X7~e7n%s}_O?T|oC?@|?%?`en8ZAkU zsN@5m%cbLAgHMn?Q(v1`ywfL1ADLRH`C)QGTRD{1GRej$qwj9aP=;I!bfeMM&mg#m zdlG|M6ZU+m1Ltj)3yo~7m>D~8ahrX_*2Ho5%T#%&!URh$i^Y_J)rube_U%Q8mgPA% zhaVqTn~_ykyuuF_Ijkc!aB~X@!1K9cbca{Y?*?uB^xzvYd`8Q;_OD+_f9|d?q$bjd z^_%}(RXV{fShYH~weM>^6Qsiw5`|PZ|AwIIT-AHYGvwGK@sjxa&w^x1K?lSJ&14x^ zqDBmqdN!=Ls&=+w_rFrw1+KK;a&Tjh(Hacr} zlrmdXul$3ki9(Nt*^ksUCTy$s<+vucQ$2VNf(o+2kh?jh*XaoDSvS<~IDUfQBm`#X ztRZeZ3}0=NAzUq2<1LGdwyH%rkuGZop#-mLt0CugCUoSAc?Ugy{A8I7oMuV-ibY*w z^Ih4SrFl8g7BL+J!UbXTPeZ=8uQKxmHkEGe-L94Cy}ItCzFlT!;UB(Q&^9$mW1#b7 z^mB;`o5h~vY-`TLR<>040(a2-dIJaWv>Xp|>P+UTszuDUjqW%V_03ibUJC7tTnU+8Qf%4lhlV_u^ldis#j4pW`JLU;XE zseR6O2BWA>j+}c^>uQzi4!FEvc}goemI^Z;0qfFh1WFUYgojO_@cho-4>|el$h!Ii zqYjK{-7gyq>H?pS(fk*_MK{n%4%Lf2MVLM^9wi`%+P{v9#DfiityXVJMip~}~)wV^;F zK7fMb1Z@M)<4UUgoD4G}D4WW{uVp_h^cW~ADmS7G1<9iIyDcqdbmv+}=Q5ZAeyjo` zLL&*VpD;NzdwDI?bf?5nzL&>XwUjYnXBF|rbYo!{4^8IwI(GNdju5pvU#3RlDFH4& zBHJS1+KSY1{BqGVfk#4=?IMrEX;wt2aYktYxZtoGXOwCHjeytxyAt}^AaF})8y!K0 z5F>5lFPHzzKP&wO3G)AcEg&?3m$V1C(}iVI>2l@!QDUL<$C_?|4;z5REzzkrbAopR zC=@E&2MAcpX>g8p`wxh*p6_R2zJS%hw8aMa>HOUXSazIAJD~?TFvQt=FTsS%kz~Jv zxBx;V))OoS=(V?@rAIP@_Em^UXeAYar&VhOL)NW;>p=TgNV%4@zBwKB@613E4vS z;a8&h&zn-PzIq@6j zxNEQRmL%XfoG%2LGVGFLF9isJndfEn-ATi_G4-im7`zGm)P0O~373Hj|+j=LAO!eS8 zHqho>yau0uokBOLlhOHonYgkENW=ZzD7eoi$Xd`Ug~$^?gHeRSgvZjtR+9;dHtOi# zgJ^3M(EEB{#o<{=A3{JO!$=uC+BC}_Ij5N%Y0KXT+L1^{jS-)NI(AUPD1zS3ELWY) zY_;pySn;TzKy?&AMVBtQB3?ijKK#~-tM-D_n0gnz!Wi*VRSVU}L_$0b zvgn`X7!*FWu%C&Fiu9{nUMe?o{ZeV?#kqJQCW>n}V47GE6L6y2--ft0yK zz5GIYqo8qpHx?D0kumbsUZ%A6p@oIxR(W~KJ0*xdmTv3JA%U;BB5DGi_(+#Oau2x% zjuw+j9VC#JB-*>t5@@A6S`fDXMq> zg>f0h25=#2$y+J|*H*3f6LKgg)nQ^Eby*}QI~rN0$!AhyYWk_uEjN8NIopW^W1WCF zLO^t5w#~4U?{UwgA1JwKwZz-o$s+pefykWc`=}t@YbXXF%u^n7-PpA9lnv}xtDgiL zv_@B!wS%1sKdvTo07zey;n0-x(e1A5UHl@6h@{5UW?zrm$t;~o{&Wo!&|15q#}$lR zIX&$D5(A4-0v*OX2~8>dWcmJ+$k4qrwREhFLA2A!Oc0}%HUw3Kp-t+X1eD#0xb_E| zzg$h)OtKmeK#rz5=5MYhtFN~u{X$&?K++%y*v~JO;ZdI!DGf)O1q~LjIKgi{xf2Lg z5!?f3XR8fP0(_e?98qjPT%QVtTJmEEODxlExG_)E3sxXO_;wOd>-NUZ?yGFnt~^f; zALdGq@~3(%kJM1tCb)WWrykI?(s^S+^ExsfvGZ@F zKhUh9Y))yJsW8B`RvnXYOyMrnhn_gLur922u~H}PE^nC{W+LfxvV}h~2SYTY>I|PZ z*Lpk-uC;BAfY^BrCCn3DsYbut?pAo`ZGA#<)d?9DDUoEm)hW(9c}IA%J9J^`jIN0O zl$-um{X`zzn~fq|bVPMDKYD&NOJt>4pOA~jeJwBA_c1mW`-9k|NK^;qeI81?mE_3q zD-e(_wbU`@IO!#;7>9C}sMb=Zfd(w4khnVB>KEBy1cN=@SjyXJ-mn{8*f8Y# z?nu<7G;mXz7veBjB`(>n9cQ#Vk(&9X<{zw9tl%u{aA(bC9}H=Re}$PE8We08=bfW~ z*K8EedYm$RwIJ*IDsw(BE8(+qTdBKPQ@)Qnu!p(4QR%Ql^;_0in;u7%h8Ysy8X)D68ev!KqCX4R z^YxbI$xQgNG{6efV>dd=g$+}eSQ~v|Cvef^e3&PkaFz{wQpJ{2D(cIb<@K{$-|X*G zI_%Y!enjFye2Y@ToQCjN&4v?0T}h&usE1S;bvfq@i>rCWlYzPVo)apS=K2J zsUjg%J-rD~S#*RqEA_hQ-#Cx^gY)6xZ6}l^3wuAb<0UrQfK6ZDSJ5c6STqK^Z0aC( z9X{VYIDq9MbipC>l_A#D?o}%dAv#e)%;1XKfOEp_Qbs?&>JOpHty8=Y#57--cdV#liUl=eEH15s2=#!c>=H7suWuGq`S_C~PO#QV9& zW`vNqIZCfwkk&3U*9XQVV%CIx5#W>5N0@8CPxUg8F3S#YsTo+iR%_*Zdo-dnA`s@?~A(J2^bA)n~d5z=VsKNm!f zKSS`Y{l7i~#0FNp;1V<(hw|4c@X<|x8y31Aqzn>I0ohz^k0v^5M=x_H@~u7qK|#YYLYXT@90GKf$bkMK=oLU z4gLSP9sme?LR+}t!+Hb!HScfGn0tW2A?s=I)6IwjKLKQ2e6KS+}0vLf@M(nyIzX8h9k{?2rZpg+aF(Jj1wP>nsQN%F z(vmkE=Sm;s zHsrjBEqZ}R$Qc4_c^)Ri|Ldxc{|IJP(F5(d1OY@;K=>%+K488DZmI@OhG77Q7VwFP z7RcwFmMuaaoQWZQXr|yHEL{LyypR{<;tk^8{%`f3uwv%UZ`@d%!4MA4xK1b;7wXsr zBETKSNWeh^9RKpl@{Aka+)-TR6e!aAkahWg98tu=B->c{WCB|40fHh4lM;W+7H}_iuPOi zZXM9bhJ{ioKU)DR^ z2IBdq{qa4OY`f~;Y@jnGCiO_j{|a*b{>0$-$uFHi`I;Rz^G|GE|9+c(`Nh3i*Dv2J zv&?h5-nb@Q_S}kBv)8@e1xCMie+&G)`}P^} { const authProviders = await getAuthProviders(project); - return authProviders.length > 0; + + // @TODO: Eventually can deprecate old basic auth setup and remove the TOOLPAD_BASIC_AUTH_USER check + return authProviders.length > 0 || !!process.env.TOOLPAD_BASIC_AUTH_USER; } function getMappedRoles( @@ -141,25 +143,38 @@ export function createAuthHandler(project: ToolpadProject): Router { name: 'Credentials', async authorize({ username, password }) { if (process.env.NODE_ENV !== 'test') { - throw new Error('Credentials authentication provider can only be used in test mode.'); - } + // @TODO: Eventually can deprecate old environment variable names (TOOLPAD_BASIC_AUTH...) + const authUsername = + process.env.TOOLPAD_AUTH_USERNAME ?? process.env.TOOLPAD_BASIC_AUTH_USER; + const authPassword = + process.env.TOOLPAD_AUTH_PASSWORD ?? process.env.TOOLPAD_BASIC_AUTH_PASSWORD; + + if ( + authUsername && + authPassword && + username === authUsername && + password === authPassword + ) { + return { id: 'user', name: 'User', email: 'user@mui.com', roles: [] }; + } + } else { + if (username === 'admin' && password === 'admin') { + return { + id: 'admin', + name: 'Lord Admin', + email: 'admin@example.com', + roles: ['mock-admin'], + }; + } + if (username === 'mui' && password === 'mui') { + return { id: 'mui', name: 'Mr. MUI 2024', email: 'test@mui.com', roles: [] }; + } + if (username === 'test' && password === 'test') { + return { id: 'test', name: 'Miss Test', email: 'test@example.com', roles: [] }; + } - if (username === 'admin' && password === 'admin') { - return { - id: 'admin', - name: 'Lord Admin', - email: 'admin@example.com', - roles: ['mock-admin'], - }; - } - if (username === 'mui' && password === 'mui') { - return { id: 'mui', name: 'Mr. MUI 2024', email: 'test@mui.com', roles: [] }; + return null; } - if (username === 'test' && password === 'test') { - return { id: 'test', name: 'Miss Test', email: 'test@example.com', roles: [] }; - } - - return null; }, }); diff --git a/packages/toolpad-app/src/server/basicAuth.ts b/packages/toolpad-app/src/server/basicAuth.ts deleted file mode 100644 index e511bcaf81..0000000000 --- a/packages/toolpad-app/src/server/basicAuth.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { IncomingMessage, ServerResponse } from 'http'; -import config from './config'; - -export function checkBasicAuthHeader(headerContent: string | null): boolean { - if (!config.basicAuthUser) { - return true; - } - - if (headerContent) { - const auth = headerContent.split(' ')[1]; - const [user, pwd] = atob(auth).toString().split(':'); - - if (user === config.basicAuthUser && pwd === config.basicAuthPassword) { - return true; - } - } - - return false; -} - -export function checkBasicAuth(req: IncomingMessage): boolean { - return checkBasicAuthHeader(req.headers.authorization || null); -} - -export function basicAuthUnauthorized(res: ServerResponse): void { - res.setHeader('WWW-Authenticate', 'Basic realm="Protected"'); - res.statusCode = 401; - res.end('Unauthorized'); -} diff --git a/packages/toolpad-app/src/server/config.ts b/packages/toolpad-app/src/server/config.ts index e40ea6bb58..f4960cd6a7 100644 --- a/packages/toolpad-app/src/server/config.ts +++ b/packages/toolpad-app/src/server/config.ts @@ -1,21 +1,9 @@ -type BasicAuthConfig = - | { - basicAuthUser: string; - basicAuthPassword: string; - } - | { - basicAuthUser?: undefined; - basicAuthPassword?: undefined; - }; - export type ServerConfig = { databaseUrl?: string; googleSheetsClientId?: string; googleSheetsClientSecret?: string; encryptionKeys: string[]; - basicAuthUser?: string; - basicAuthPassword?: string; -} & BasicAuthConfig; +}; function readConfig(): ServerConfig { if (typeof window !== 'undefined') { @@ -26,20 +14,7 @@ function readConfig(): ServerConfig { const encryptionKeys: string[] = process.env.TOOLPAD_ENCRYPTION_KEYS?.split(/\s+/).filter(Boolean) ?? []; - let basicAuthConfig: BasicAuthConfig = {}; - if (process.env.TOOLPAD_BASIC_AUTH_USER && process.env.TOOLPAD_BASIC_AUTH_PASSWORD) { - basicAuthConfig = { - basicAuthUser: process.env.TOOLPAD_BASIC_AUTH_USER, - basicAuthPassword: process.env.TOOLPAD_BASIC_AUTH_PASSWORD, - }; - } else if (process.env.TOOLPAD_BASIC_AUTH_USER) { - throw new Error( - `Basic Auth user configured without password. Please provide the TOOLPAD_BASIC_AUTH_PASSWORD environment variable.`, - ); - } - return { - ...basicAuthConfig, databaseUrl: process.env.TOOLPAD_DATABASE_URL, googleSheetsClientId: process.env.TOOLPAD_DATASOURCE_GOOGLESHEETS_CLIENT_ID, googleSheetsClientSecret: process.env.TOOLPAD_DATASOURCE_GOOGLESHEETS_CLIENT_SECRET, diff --git a/packages/toolpad-app/src/server/toolpadAppServer.ts b/packages/toolpad-app/src/server/toolpadAppServer.ts index 6c7c242271..7caa4bd553 100644 --- a/packages/toolpad-app/src/server/toolpadAppServer.ts +++ b/packages/toolpad-app/src/server/toolpadAppServer.ts @@ -5,7 +5,6 @@ import * as express from 'express'; import serializeJavascript from 'serialize-javascript'; import { ToolpadProject } from './localMode'; import { asyncHandler } from '../utils/express'; -import { basicAuthUnauthorized, checkBasicAuthHeader } from './basicAuth'; import { createRpcServer } from './runtimeRpcServer'; import { createRpcHandler } from './rpc'; import { RUNTIME_CONFIG_WINDOW_PROPERTY, INITIAL_STATE_WINDOW_PROPERTY } from '../constants'; @@ -54,15 +53,6 @@ export async function createProdHandler(project: ToolpadProject) { handler.use(express.static(project.getAppOutputFolder(), { index: false })); - // Allow static assets, block everything else - handler.use((req, res, next) => { - if (checkBasicAuthHeader(req.headers.authorization ?? null)) { - next(); - return; - } - basicAuthUnauthorized(res); - }); - const hasAuthentication = await getRequireAuthentication(project); if (hasAuthentication) { const authHandler = createAuthHandler(project); diff --git a/packages/toolpad-app/src/toolpad/AppEditor/AppAuthorizationEditor.tsx b/packages/toolpad-app/src/toolpad/AppEditor/AppAuthorizationEditor.tsx index c7573258f4..0d345c4cbd 100644 --- a/packages/toolpad-app/src/toolpad/AppEditor/AppAuthorizationEditor.tsx +++ b/packages/toolpad-app/src/toolpad/AppEditor/AppAuthorizationEditor.tsx @@ -35,6 +35,7 @@ import { } from '@mui/x-data-grid'; import GitHubIcon from '@mui/icons-material/GitHub'; import GoogleIcon from '@mui/icons-material/Google'; +import PasswordIcon from '@mui/icons-material/Password'; import { TabContext, TabList } from '@mui/lab'; import { updateArray } from '@mui/toolpad-utils/immutability'; import * as appDom from '@mui/toolpad-core/appDom'; @@ -60,6 +61,14 @@ const AUTH_PROVIDER_OPTIONS = new Map([ hasRoles: true, }, ], + [ + 'credentials', + { + name: 'Credentials', + icon: , + hasRoles: false, + }, + ], ]); export function AppAuthenticationEditor() { diff --git a/test/integration/auth/basic.spec.ts b/test/integration/auth/basic.spec.ts new file mode 100644 index 0000000000..11f922a60e --- /dev/null +++ b/test/integration/auth/basic.spec.ts @@ -0,0 +1,40 @@ +import * as path from 'path'; +import * as url from 'url'; +import { test, expect } from '../../playwright/localTest'; +import { tryCredentialsSignIn } from './shared'; + +const currentDirectory = url.fileURLToPath(new URL('.', import.meta.url)); + +test.use({ + ignoreConsoleErrors: [ + /Failed to load resource: the server responded with a status of 401 \(Unauthorized\)/, + ], +}); + +test.use({ + projectConfig: { + template: path.resolve(currentDirectory, './fixture-basic'), + }, + localAppConfig: { + cmd: 'start', + env: { + TOOLPAD_AUTH_SECRET: 'donttellanyone', + TOOLPAD_AUTH_USERNAME: 'foo', + TOOLPAD_AUTH_PASSWORD: 'bar', + }, + }, +}); + +test('Must be authenticated with correct credentials to access app', async ({ page }) => { + await page.goto('/prod/pages/mypage'); + + // Sign in with invalid credentials + await tryCredentialsSignIn(page, 'foo', 'wrongpassword'); + await expect(page).toHaveURL(/\/prod\/signin/); + await expect(page.getByText('Invalid credentials.')).toBeVisible(); + + // Sign in with valid credentials + await tryCredentialsSignIn(page, 'foo', 'bar'); + await expect(page).toHaveURL(/\/prod\/pages\/mypage/); + await expect(page.getByText('message: hello world')).toBeVisible(); +}); diff --git a/test/integration/auth/domain.spec.ts b/test/integration/auth/domain.spec.ts index 1de9c69d3d..cd03cc6511 100644 --- a/test/integration/auth/domain.spec.ts +++ b/test/integration/auth/domain.spec.ts @@ -32,7 +32,7 @@ test('Must be authenticated with valid domain to access app', async ({ page, req await expect(page).toHaveURL(/\/prod\/signin/); // Access is blocked to API route - const res = await request.post('/prod/api/data/page/hello'); + const res = await request.post('/prod/api/data/page/getMySession'); expect(res.status()).toBe(401); // Sign in with invalid domain diff --git a/test/integration/basic-auth/fixture/toolpad/.gitignore b/test/integration/auth/fixture-basic/.gitignore similarity index 100% rename from test/integration/basic-auth/fixture/toolpad/.gitignore rename to test/integration/auth/fixture-basic/.gitignore diff --git a/test/integration/auth/fixture-basic/application.yml b/test/integration/auth/fixture-basic/application.yml new file mode 100644 index 0000000000..dbfeb18087 --- /dev/null +++ b/test/integration/auth/fixture-basic/application.yml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: application +spec: + authentication: + providers: [{ provider: credentials }] diff --git a/test/integration/basic-auth/fixture/toolpad/pages/page1/page.yml b/test/integration/auth/fixture-basic/pages/mypage/page.yml similarity index 95% rename from test/integration/basic-auth/fixture/toolpad/pages/page1/page.yml rename to test/integration/auth/fixture-basic/pages/mypage/page.yml index 8f8100eca1..31ebc4c034 100644 --- a/test/integration/basic-auth/fixture/toolpad/pages/page1/page.yml +++ b/test/integration/auth/fixture-basic/pages/mypage/page.yml @@ -2,7 +2,7 @@ apiVersion: v1 kind: page spec: id: 5q1xd0t - title: Page 1 + title: Page content: - component: PageRow name: pageRow diff --git a/test/integration/basic-auth/fixture/toolpad/resources/functions.ts b/test/integration/auth/fixture-basic/resources/functions.ts similarity index 100% rename from test/integration/basic-auth/fixture/toolpad/resources/functions.ts rename to test/integration/auth/fixture-basic/resources/functions.ts diff --git a/test/integration/basic-auth/prod.spec.ts b/test/integration/basic-auth/prod.spec.ts deleted file mode 100644 index 5e0f2e3839..0000000000 --- a/test/integration/basic-auth/prod.spec.ts +++ /dev/null @@ -1,55 +0,0 @@ -import * as path from 'path'; -import * as url from 'url'; -import invariant from 'invariant'; -import { test, expect } from '../../playwright/localTest'; - -const currentDirectory = url.fileURLToPath(new URL('.', import.meta.url)); - -test.use({ - ignoreConsoleErrors: [ - /Failed to load resource: the server responded with a status of 401 \(Unauthorized\)/, - ], -}); - -test.use({ - projectConfig: { - template: path.resolve(currentDirectory, './fixture'), - }, - localAppConfig: { - cmd: 'start', - env: { - TOOLPAD_BASIC_AUTH_USER: 'foo', - TOOLPAD_BASIC_AUTH_PASSWORD: 'bar', - }, - }, -}); - -test('Access is blocked', async ({ page }) => { - const res = await page.goto('/prod/pages/page1'); - expect(res?.status()).toBe(401); -}); - -test('Access is blocked to API route', async ({ request }) => { - const res = await request.post('/prod/api/data/page1/hello'); - expect(res.status()).toBe(401); -}); - -test('Access is granted when authenticated', async ({ browserName, page, localApp }) => { - invariant( - localApp, - 'test must be configured with `localAppConfig`. Add `test.use({ localAppConfig: ... })`', - ); - - test.skip( - browserName === 'firefox', - 'Fails due to https://bugzilla.mozilla.org/show_bug.cgi?id=1742396', - ); - - const appUrl = new URL(localApp.url); - appUrl.username = 'foo'; - appUrl.password = 'bar'; - - const res = await page.goto(appUrl.href); - expect(res?.status()).toBe(200); - await expect(page.locator('text="message: hello world"')).toBeVisible(); -});