I am having problem with CheckoutAuthGuard
on spartacus storefront. When browser refresh button is pressed on any page in checkout process, guard redirects me to a login due to missing user and cart info.
I have used CustomCheckoutAuthGuard
like this:
import { Injectable } from '@angular/core';
import {CanActivate, Router} from '@angular/router';
import {
ActiveCartService,
AuthRedirectService,
AuthService,
RoutingService,
User,
UserToken,
} from '@spartacus/core';
import { combineLatest, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import {CheckoutConfigService} from '@spartacus/storefront';
@Injectable()
export class CustomCheckoutAuthGuard implements CanActivate {
constructor(
protected routingService: RoutingService,
protected authService: AuthService,
protected authRedirectService: AuthRedirectService,
protected checkoutConfigService: CheckoutConfigService,
protected activeCartService: ActiveCartService,
private router: Router
) {}
canActivate(): Observable<boolean> {
return combineLatest([
this.authService.getUserToken(),
this.activeCartService.getAssignedUser(),
]).pipe(
map(([token, user]: [UserToken, User]) => {
if (!token.access_token) {
if (this.activeCartService.isGuestCart()) {
return Boolean(user);
}
if (this.checkoutConfigService.isGuestCheckout()) {
this.router.navigate(['checkout-login']);
} else {
this.routingService.go({ cxRoute: 'login' });
}
this.authRedirectService.reportAuthGuard();
}
return !!token.access_token;
})
);
}
}
It is very similar to default CheckoutAuthGuard
from spartacus. I also switched this guard for all relevant checkout components:
CheckoutOrchestrator: {
component: CheckoutOrchestratorComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard, CheckoutGuard],
},
CheckoutProgressMobileTop: {
component: CheckoutProgressMobileTopComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard],
},
CheckoutProgressMobileBottomComponent: {
component: CheckoutProgressMobileBottomComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard]
},
CheckoutProgress: {
component: CheckoutProgressComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard]
},
CheckoutDeliveryMode: {
component: DeliveryModeComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard, ShippingAddressSetGuard]
},
CheckoutPlaceOrder: {
component: PlaceOrderComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard]
},
CheckoutReviewOrder: {
component: ReviewSubmitComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard]
},
CheckoutShippingAddress: {
component: ShippingAddressComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard, CheckoutDetailsLoadedGuard]
}
But on refresh, user from ActiveCartService
is undefined
and also this.activeCartService.isGuestCart()
returns undefined
.
This is all for guest checkout and unfortunately I can not tell what is behavior for logged in user. It is because we use CDC, and currently with CDC there is a bug where any refresh redirects to home page, so this guard is completely bypassed. More on this issue here.
Can someone give me advice what is best to try out here? Maybe some cart state needs to be synced with local storage, or combineLatest
is wrong rxjs
function here? Or something else? Thanks in advance!