Skip to content

Commit

Permalink
fix(auth): properly authenticate new endpoints
Browse files Browse the repository at this point in the history
refs #247
  • Loading branch information
ygrishajev committed Aug 7, 2024
1 parent df288fd commit bedc221
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 14 deletions.
19 changes: 17 additions & 2 deletions apps/api/src/auth/services/auth.interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import { singleton } from "tsyringe";
import { AbilityService } from "@src/auth/services/ability/ability.service";
import { AuthService } from "@src/auth/services/auth.service";
import type { HonoInterceptor } from "@src/core/types/hono-interceptor.type";
import { getCurrentUserId } from "@src/middlewares/userMiddleware";
import { kvStore } from "@src/middlewares/userMiddleware";
import { UserRepository } from "@src/user/repositories";
import { env } from "@src/utils/env";
import { getJwks, useKVStore, verify } from "@src/verify-rsa-jwt-cloudflare-worker-main";

@singleton()
export class AuthInterceptor implements HonoInterceptor {
Expand All @@ -17,7 +19,7 @@ export class AuthInterceptor implements HonoInterceptor {

intercept() {
return async (c: Context, next: Next) => {
const userId = getCurrentUserId(c);
const userId = await this.authenticate(c);

if (userId) {
const currentUser = await this.userRepository.findByUserId(userId);
Expand All @@ -43,4 +45,17 @@ export class AuthInterceptor implements HonoInterceptor {
return await next();
};
}

private async authenticate(c: Context) {
const jwtToken = c.req.header("Authorization")?.replace(/Bearer\s+/i, "");

if (!jwtToken?.length) {
return;
}

const jwks = await getJwks(env.Auth0JWKSUri || c.env.JWKS_URI, useKVStore(kvStore || c.env?.VERIFY_RSA_JWT), c.env?.VERIFY_RSA_JWT_JWKS_CACHE_KEY);
const result = await verify(jwtToken, jwks);

return (result.payload as { sub: string }).sub;
}
}
2 changes: 2 additions & 0 deletions apps/api/src/services/db/userDataService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ export async function getSettingsOrInit({ anonymousUserId, userId, wantedUsernam
}

return pick(userSettings, [
"id",
"userId",
"username",
"email",
"emailVerified",
Expand Down
9 changes: 6 additions & 3 deletions apps/deploy-web/src/hooks/useManagedWallet.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { useEffect, useMemo } from "react";

import { envConfig } from "@src/config/env.config";
import { useCustomUser } from "@src/hooks/useCustomUser";
import { useStoredAnonymousUser } from "@src/hooks/useStoredAnonymousUser";
import { useCreateManagedWalletMutation, useManagedWalletQuery } from "@src/queries/useManagedWalletQuery";
import { deleteManagedWalletFromStorage, updateStorageManagedWallet } from "@src/utils/walletUtils";

const isBillingEnabled = envConfig.NEXT_PUBLIC_BILLING_ENABLED;

export const useManagedWallet = () => {
const { user } = useStoredAnonymousUser();
const { user: registeredUser } = useCustomUser();
const { user: anonymousUser } = useStoredAnonymousUser();
const user = useMemo(() => registeredUser || anonymousUser, [registeredUser, anonymousUser]);

const { data: queried, isFetched, isLoading: isFetching, refetch } = useManagedWalletQuery(isBillingEnabled && user?.id);
const { mutate: create, data: created, isLoading: isCreating, isSuccess: isCreated } = useCreateManagedWalletMutation();
Expand All @@ -35,7 +38,7 @@ export const useManagedWallet = () => {
throw new Error("Billing is not enabled");
}

if (!user) {
if (!user?.id) {
throw new Error("User is not initialized yet");
}

Expand All @@ -51,5 +54,5 @@ export const useManagedWallet = () => {
isLoading,
refetch
};
}, [create, isLoading, user, wallet, refetch]);
}, [create, isLoading, user?.id, wallet, refetch]);
};
2 changes: 1 addition & 1 deletion apps/deploy-web/src/hooks/useStoredAnonymousUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const useStoredAnonymousUser = (): UseApiUserResult => {
});

useWhen(user, () => localStorage.setItem("anonymous-user", JSON.stringify(user)));
useWhen(storedAnonymousUser && registeredUser, () => localStorage.removeItem(ANONYMOUS_USER_KEY));
useWhen(registeredUser?.id, () => localStorage.removeItem(ANONYMOUS_USER_KEY));

return useMemo(
() => ({
Expand Down
14 changes: 6 additions & 8 deletions apps/deploy-web/src/services/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,18 @@ import { InternalAxiosRequestConfig } from "axios";
import { ANONYMOUS_USER_KEY } from "@src/utils/constants";

export class AuthService {
private anonymousUserId: string | undefined;

constructor() {
this.withAnonymousUserHeader = this.withAnonymousUserHeader.bind(this);
}

withAnonymousUserHeader(config: InternalAxiosRequestConfig) {
if (!this.anonymousUserId) {
const user = localStorage.getItem(ANONYMOUS_USER_KEY);
this.anonymousUserId = user ? JSON.parse(user).id : undefined;
}
const user = localStorage.getItem(ANONYMOUS_USER_KEY);
const anonymousUserId = user ? JSON.parse(user).id : undefined;

if (this.anonymousUserId) {
config.headers.set("x-anonymous-user-id", this.anonymousUserId);
if (anonymousUserId) {
config.headers.set("x-anonymous-user-id", anonymousUserId);
} else {
config.baseURL = "/api/proxy";
}

return config;
Expand Down
2 changes: 2 additions & 0 deletions apps/deploy-web/src/types/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export interface SdlTemplate {
}

export interface UserSettings {
id?: string;
userId?: string;
username?: string;
subscribedToNewsletter?: boolean;
bio?: string;
Expand Down

0 comments on commit bedc221

Please sign in to comment.