remove current phone number from session

This commit is contained in:
m5r 2022-06-11 02:45:07 +02:00
parent 3ddd0d73ea
commit 836b1d8d1b
9 changed files with 47 additions and 48 deletions

View File

@ -12,7 +12,10 @@ export type KeypadLoaderData = {
}; };
const loader: LoaderFunction = async ({ request }) => { const loader: LoaderFunction = async ({ request }) => {
const { phoneNumber } = await requireLoggedIn(request); const { twilio } = await requireLoggedIn(request);
const phoneNumber = await db.phoneNumber.findUnique({
where: { twilioAccountSid_isCurrent: { twilioAccountSid: twilio?.accountSid ?? "", isCurrent: true } },
});
const hasOngoingSubscription = true; // TODO const hasOngoingSubscription = true; // TODO
const hasPhoneNumber = Boolean(phoneNumber); const hasPhoneNumber = Boolean(phoneNumber);
const lastCall = const lastCall =

View File

@ -8,12 +8,17 @@ import getTwilioClient, { translateMessageDirection, translateMessageStatus } fr
export type NewMessageActionData = {}; export type NewMessageActionData = {};
const action: ActionFunction = async ({ params, request }) => { const action: ActionFunction = async ({ params, request }) => {
const { phoneNumber, twilio } = await requireLoggedIn(request); const { twilio } = await requireLoggedIn(request);
if (!twilio) { if (!twilio) {
throw new Error("unreachable"); throw new Error("unreachable");
} }
const twilioAccount = await db.twilioAccount.findUnique({ where: { accountSid: twilio.accountSid } }); const [phoneNumber, twilioAccount] = await Promise.all([
if (!twilioAccount) { db.phoneNumber.findUnique({
where: { twilioAccountSid_isCurrent: { twilioAccountSid: twilio.accountSid ?? "", isCurrent: true } },
}),
db.twilioAccount.findUnique({ where: { accountSid: twilio.accountSid } }),
]);
if (!phoneNumber || !twilioAccount) {
throw new Error("unreachable"); throw new Error("unreachable");
} }
@ -24,11 +29,11 @@ const action: ActionFunction = async ({ params, request }) => {
const message = await twilioClient.messages.create({ const message = await twilioClient.messages.create({
body: formData.content.toString(), body: formData.content.toString(),
to: recipient, to: recipient,
from: phoneNumber!.number, from: phoneNumber.number,
}); });
await db.message.create({ await db.message.create({
data: { data: {
phoneNumberId: phoneNumber!.id, phoneNumberId: phoneNumber.id,
id: message.sid, id: message.sid,
to: message.to, to: message.to,
recipient: message.to, recipient: message.to,

View File

@ -7,13 +7,11 @@ import { Direction } from "@prisma/client";
import NewMessageArea from "./new-message-area"; import NewMessageArea from "./new-message-area";
import { formatDate, formatTime } from "~/features/core/helpers/date-formatter"; import { formatDate, formatTime } from "~/features/core/helpers/date-formatter";
import { type ConversationLoaderData } from "~/features/messages/loaders/messages.$recipient"; import { type ConversationLoaderData } from "~/features/messages/loaders/messages.$recipient";
import useSession from "~/features/core/hooks/use-session";
export default function Conversation() { export default function Conversation() {
const { phoneNumber } = useSession();
const params = useParams<{ recipient: string }>(); const params = useParams<{ recipient: string }>();
const recipient = decodeURIComponent(params.recipient ?? ""); const recipient = decodeURIComponent(params.recipient ?? "");
const { conversation } = useLoaderData<ConversationLoaderData>(); const { conversation, currentPhoneNumber } = useLoaderData<ConversationLoaderData>();
const transition = useTransition(); const transition = useTransition();
const messagesListRef = useRef<HTMLUListElement>(null); const messagesListRef = useRef<HTMLUListElement>(null);
@ -21,8 +19,8 @@ export default function Conversation() {
if (transition.submission) { if (transition.submission) {
messages.push({ messages.push({
id: "temp", id: "temp",
phoneNumberId: phoneNumber!.id, phoneNumberId: currentPhoneNumber!.id,
from: phoneNumber!.number, from: currentPhoneNumber!.number,
to: recipient, to: recipient,
recipient, recipient,
sentAt: new Date(), sentAt: new Date(),

View File

@ -1,7 +1,7 @@
import type { LoaderFunction } from "@remix-run/node"; import type { LoaderFunction } from "@remix-run/node";
import { json } from "superjson-remix"; import { json } from "superjson-remix";
import { parsePhoneNumber } from "awesome-phonenumber"; import { parsePhoneNumber } from "awesome-phonenumber";
import { type Message, Prisma } from "@prisma/client"; import { type Message, type PhoneNumber, Prisma } from "@prisma/client";
import db from "~/utils/db.server"; import db from "~/utils/db.server";
import { requireLoggedIn } from "~/utils/auth.server"; import { requireLoggedIn } from "~/utils/auth.server";
@ -15,6 +15,7 @@ type ConversationType = {
export type ConversationLoaderData = { export type ConversationLoaderData = {
conversation: ConversationType; conversation: ConversationType;
currentPhoneNumber: Pick<PhoneNumber, "id" | "number">;
}; };
const loader: LoaderFunction = async ({ request, params }) => { const loader: LoaderFunction = async ({ request, params }) => {
@ -24,10 +25,26 @@ const loader: LoaderFunction = async ({ request, params }) => {
} }
const twilioAccountSid = twilio.accountSid; const twilioAccountSid = twilio.accountSid;
const currentPhoneNumber = await db.phoneNumber.findUnique({
where: {
twilioAccountSid_isCurrent: {
twilioAccountSid,
isCurrent: true,
},
},
select: {
id: true,
number: true,
},
});
if (!currentPhoneNumber) {
return redirect("/messages");
}
const recipient = decodeURIComponent(params.recipient ?? ""); const recipient = decodeURIComponent(params.recipient ?? "");
const conversation = await getConversation(recipient); const conversation = await getConversation(recipient);
return json<ConversationLoaderData>({ conversation }); return json<ConversationLoaderData>({ conversation, currentPhoneNumber });
async function getConversation(recipient: string): Promise<ConversationType> { async function getConversation(recipient: string): Promise<ConversationType> {
const phoneNumber = await db.phoneNumber.findUnique({ const phoneNumber = await db.phoneNumber.findUnique({

View File

@ -19,12 +19,10 @@ type Conversation = {
}; };
const loader: LoaderFunction = async ({ request }) => { const loader: LoaderFunction = async ({ request }) => {
const sessionData = await requireLoggedIn(request); const { twilio } = await requireLoggedIn(request);
const phoneNumber = const phoneNumber = await db.phoneNumber.findUnique({
sessionData.phoneNumber && where: { twilioAccountSid_isCurrent: { twilioAccountSid: twilio?.accountSid ?? "", isCurrent: true } },
(await db.phoneNumber.findUnique({ });
where: { id: sessionData.phoneNumber.id },
}));
return json<MessagesLoaderData>({ return json<MessagesLoaderData>({
hasPhoneNumber: Boolean(phoneNumber), hasPhoneNumber: Boolean(phoneNumber),
isFetchingMessages: phoneNumber?.isFetchingMessages ?? null, isFetchingMessages: phoneNumber?.isFetchingMessages ?? null,

View File

@ -26,20 +26,12 @@ export type PhoneCallsLoaderData = {
); );
const loader: LoaderFunction = async ({ request }) => { const loader: LoaderFunction = async ({ request }) => {
const sessionData = await requireLoggedIn(request); const { twilio } = await requireLoggedIn(request);
const hasOngoingSubscription = true; // TODO
const hasPhoneNumber = Boolean(sessionData.phoneNumber);
if (!sessionData.phoneNumber) {
return json<PhoneCallsLoaderData>({
hasOngoingSubscription,
hasPhoneNumber: false,
isFetchingCalls: false,
});
}
const phoneNumber = await db.phoneNumber.findUnique({ const phoneNumber = await db.phoneNumber.findUnique({
where: { id: sessionData.phoneNumber.id }, where: { twilioAccountSid_isCurrent: { twilioAccountSid: twilio?.accountSid ?? "", isCurrent: true } },
}); });
const hasPhoneNumber = Boolean(phoneNumber);
const hasOngoingSubscription = true; // TODO
if (!phoneNumber || phoneNumber.isFetchingCalls) { if (!phoneNumber || phoneNumber.isFetchingCalls) {
return json<PhoneCallsLoaderData>({ return json<PhoneCallsLoaderData>({
hasOngoingSubscription, hasOngoingSubscription,

View File

@ -75,16 +75,8 @@ async function setPhoneNumber(request: Request, formData: unknown) {
phoneNumberId: validation.data.phoneNumberSid, phoneNumberId: validation.data.phoneNumberSid,
organizationId: organization.id, organizationId: organization.id,
}); });
const { session } = await refreshSessionData(request);
return json<SetPhoneNumberActionData>( return json<SetPhoneNumberActionData>({ setPhoneNumber: { submitted: true } });
{ setPhoneNumber: { submitted: true } },
{
headers: {
"Set-Cookie": await commitSession(session),
},
},
);
} }
export type SetTwilioCredentialsActionData = FormActionData<typeof validations, "setTwilioCredentials">; export type SetTwilioCredentialsActionData = FormActionData<typeof validations, "setTwilioCredentials">;

View File

@ -10,7 +10,7 @@ import type { SetPhoneNumberActionData } from "~/features/settings/actions/phone
import clsx from "clsx"; import clsx from "clsx";
export default function PhoneNumberForm() { export default function PhoneNumberForm() {
const { twilio, phoneNumber } = useSession(); const { twilio } = useSession();
const fetcher = useFetcher(); const fetcher = useFetcher();
const transition = useTransition(); const transition = useTransition();
const actionData = useActionData<SetPhoneNumberActionData>()?.setPhoneNumber; const actionData = useActionData<SetPhoneNumberActionData>()?.setPhoneNumber;

View File

@ -1,7 +1,7 @@
import { redirect, type Session } from "@remix-run/node"; import { redirect, type Session } from "@remix-run/node";
import type { FormStrategyVerifyParams } from "remix-auth-form"; import type { FormStrategyVerifyParams } from "remix-auth-form";
import SecurePassword from "secure-password"; import SecurePassword from "secure-password";
import type { MembershipRole, Organization, PhoneNumber, TwilioAccount, User } from "@prisma/client"; import type { MembershipRole, Organization, TwilioAccount, User } from "@prisma/client";
import db from "./db.server"; import db from "./db.server";
import logger from "./logger.server"; import logger from "./logger.server";
@ -11,12 +11,10 @@ import { commitSession, destroySession, getSession } from "./session.server";
type SessionTwilioAccount = Pick<TwilioAccount, "accountSid" | "authToken">; type SessionTwilioAccount = Pick<TwilioAccount, "accountSid" | "authToken">;
type SessionOrganization = Pick<Organization, "id"> & { role: MembershipRole; membershipId: string }; type SessionOrganization = Pick<Organization, "id"> & { role: MembershipRole; membershipId: string };
type SessionPhoneNumber = Pick<PhoneNumber, "id" | "number">;
export type SessionUser = Pick<User, "id" | "role" | "email" | "fullName">; export type SessionUser = Pick<User, "id" | "role" | "email" | "fullName">;
export type SessionData = { export type SessionData = {
user: SessionUser; user: SessionUser;
organization: SessionOrganization; organization: SessionOrganization;
phoneNumber: SessionPhoneNumber | null;
twilio: SessionTwilioAccount | null; twilio: SessionTwilioAccount | null;
}; };
@ -198,13 +196,9 @@ async function buildSessionData(id: string): Promise<SessionData> {
membershipId: membership.id, membershipId: membership.id,
})); }));
const { twilioAccount, ...organization } = organizations[0]; const { twilioAccount, ...organization } = organizations[0];
const phoneNumber = await db.phoneNumber.findUnique({
where: { twilioAccountSid_isCurrent: { twilioAccountSid: twilioAccount?.accountSid ?? "", isCurrent: true } },
});
return { return {
user: rest, user: rest,
organization, organization,
phoneNumber,
twilio: twilioAccount, twilio: twilioAccount,
}; };
} }