Skip to content

Commit

Permalink
Web's env + wip email
Browse files Browse the repository at this point in the history
  • Loading branch information
oscartbeaumont committed Sep 14, 2024
1 parent ac93784 commit 88d7798
Show file tree
Hide file tree
Showing 30 changed files with 461 additions and 243 deletions.
10 changes: 2 additions & 8 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
VITE_PROD_ORIGIN=http://localhost:3000
DATABASE_URL='mysql://todo:[email protected]/todo?ssl={"rejectUnauthorized":true}'
MANAGE_URL=https://mdm.example.com

# Rust
INTERNAL_SECRET=areallylongsecretthatyoushouldreplace
MDM_URL=https://mdm.example.com
ENTERPRISE_ENROLLMENT_URL=https://enterpriseenrollment.example.com

# Billing
STRIPE_PUBLISHABLE_KEY=
STRIPE_SECRET_KEY=

# Syncing users
ENTRA_CLIENT_ID=
Expand All @@ -19,5 +13,5 @@ FROM_ADDRESS=console
# AWS_ACCESS_KEY_ID=
# AWS_SECRET_ACCESS_KEY=

# Used for landing only
# For `apps/landing`
VITE_MATTRAX_CLOUD_ORIGIN=http://localhost:3000 # Should point to `apps/web`
6 changes: 3 additions & 3 deletions apps/cloud/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ mod sql;
pub struct Context {
pub manage_domain: String,
pub enrollment_domain: String,
pub internal_db_secret: String,
pub internal_secret: String,
pub cert: Certificate,
pub key: KeyPair,
pub client: reqwest::Client,
Expand All @@ -40,8 +40,8 @@ impl Context {
.map_err(|_| "'MANAGE_DOMAIN' must be set")?,
enrollment_domain: std::env::var("ENROLLMENT_DOMAIN")
.map_err(|_| "'ENROLLMENT_DOMAIN' must be set")?,
internal_db_secret: std::env::var("INTERNAL_DB_SECRET")
.map_err(|_| "'INTERNAL_DB_SECRET' must be set")?,
internal_secret: std::env::var("INTERNAL_SECRET")
.map_err(|_| "'INTERNAL_SECRET' must be set")?,
cert: CertificateParams::from_ca_cert_pem(
&std::env::var("IDENTITY_CERT").map_err(|_| "'IDENTITY_CERT' must be set")?,
)
Expand Down
4 changes: 2 additions & 2 deletions apps/cloud/src/sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,9 @@ pub async fn auth(State(state): State<Arc<Context>>, request: Request, next: Nex
if authorization
!= Some(&format!(
"Basic {}",
STANDARD.encode(format!(":{}", &state.internal_db_secret))
STANDARD.encode(format!(":{}", &state.internal_secret))
))
&& authorization != Some(&format!("Bearer {}", state.internal_db_secret))
&& authorization != Some(&format!("Bearer {}", state.internal_secret))
{
return (StatusCode::UNAUTHORIZED, "Unauthorized").into_response();
}
Expand Down
12 changes: 12 additions & 0 deletions apps/landing/sst-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,22 @@ declare module "sst" {
"type": "sst.sst.Secret"
"value": string
}
"EntraClientID": {
"type": "sst.sst.Secret"
"value": string
}
"EntraClientSecret": {
"type": "sst.sst.Secret"
"value": string
}
"cloud": {
"name": string
"type": "sst.aws.Function"
"url": string
}
"email": {
"sender": string
"type": "sst.aws.Email"
}
}
}
5 changes: 1 addition & 4 deletions apps/web/src/api/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,7 @@ export const checkAuth = cache(async () => {
function getCookieDomain(event: RequestEvent) {
const url = new URL(event.request.url);
let domain = env.COOKIE_DOMAIN;
if (
env.PREVIEW_DOMAIN_SUFFIX &&
url.hostname.endsWith(env.PREVIEW_DOMAIN_SUFFIX)
) {
if (url.hostname.endsWith(".pages.dev")) {
domain = undefined;
}
return domain;
Expand Down
4 changes: 0 additions & 4 deletions apps/web/src/api/rest/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ export const app = new Hono<HonoEnv>()
.route("/waitlist", waitlistRouter)
.route("/webhook", webhookRouter)
.route("/ms", msRouter)
.get("/where_da_rust", async (c) => {
c.header("Cache-Control", "public,max-age=600,must-revalidate");
return c.text(env.MDM_URL);
})
.all("*", (c) => {
c.status(404);
if (c.req.raw.headers.get("Accept")?.includes("application/json")) {
Expand Down
32 changes: 16 additions & 16 deletions apps/web/src/api/stripe.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { env } from "~/env";
// import { env } from "~/env";

export async function useStripe() {
const secret = env.STRIPE_SECRET_KEY;
if (!secret) throw new Error("Missing 'STRIPE_SECRET_KEY'");
// export async function useStripe() {
// const secret = env.STRIPE_SECRET_KEY;
// if (!secret) throw new Error("Missing 'STRIPE_SECRET_KEY'");

return import("stripe").then((mod) => {
const Stripe = mod.default;
// return import("stripe").then((mod) => {
// const Stripe = mod.default;

return Object.assign(
new Stripe(secret, {
apiVersion: "2024-06-20",
timeout: 1500,
httpClient: Stripe.createFetchHttpClient(),
}),
{ secret },
);
});
}
// return Object.assign(
// new Stripe(secret, {
// apiVersion: "2024-06-20",
// timeout: 1500,
// httpClient: Stripe.createFetchHttpClient(),
// }),
// { secret },
// );
// });
// }
5 changes: 2 additions & 3 deletions apps/web/src/api/trpc/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { db, organisationMembers, organisations, tenants } from "~/db";
import { withAccount } from "../account";
import { checkAuth } from "../auth";
import { withTenant } from "../tenant";
import { invalidate } from "../utils/realtime";

export const createTRPCContext = (event: H3Event) => {
return {
Expand Down Expand Up @@ -159,7 +158,7 @@ export const orgProcedure = authedProcedure

return opts.next({ ctx: { ...ctx, org } }).then((result) => {
// TODO: Right now we invalidate everything but we will need to be more specific in the future
if (type === "mutation") invalidate(org.slug);
// if (type === "mutation") invalidate(org.slug);
return result;
});
});
Expand Down Expand Up @@ -198,7 +197,7 @@ export const tenantProcedure = authedProcedure
return withTenant(tenant, () =>
opts.next({ ctx: { ...ctx, tenant } }).then((result) => {
// TODO: Right now we invalidate everything but we will need to be more specific in the future
if (type === "mutation") invalidate(tenant.orgSlug, input.tenantSlug);
// if (type === "mutation") invalidate(tenant.orgSlug, input.tenantSlug);
return result;
}),
);
Expand Down
5 changes: 2 additions & 3 deletions apps/web/src/api/trpc/routers/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { z } from "zod";
import { TRPCError } from "@trpc/server";
import { withTenant } from "~/api/tenant";
import { omit } from "~/api/utils";
import { invalidate } from "~/api/utils/realtime";
import { createEnrollmentSession } from "~/app/enroll/util";
import {
applicationAssignables,
Expand Down Expand Up @@ -33,7 +32,7 @@ const deviceProcedure = authedProcedure
return withTenant(tenant, () =>
next({ ctx: { device, tenant } }).then((result) => {
// TODO: Right now we invalidate everything but we will need to be more specific in the future
if (type === "mutation") invalidate(tenant.orgSlug, tenant.slug);
// if (type === "mutation") invalidate(tenant.orgSlug, tenant.slug);
return result;
}),
);
Expand Down Expand Up @@ -224,7 +223,7 @@ export const deviceRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const p = new URLSearchParams();
p.set("mode", "mdm");
p.set("servername", env.ENTERPRISE_ENROLLMENT_URL);
p.set("servername", env.VITE_PROD_ORIGIN);

let data: { uid: number; upn: string } | undefined = undefined;
if (input.userId) {
Expand Down
3 changes: 1 addition & 2 deletions apps/web/src/api/trpc/routers/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { z } from "zod";
import { cache } from "@solidjs/router";
import { createAuditLog } from "~/api/auditLog";
import { withTenant } from "~/api/tenant";
import { invalidate } from "~/api/utils/realtime";
import { createTransaction } from "~/api/utils/transaction";
import {
GroupMemberVariants,
Expand Down Expand Up @@ -43,7 +42,7 @@ const groupProcedure = authedProcedure
return withTenant(tenant, () =>
next({ ctx: { group, tenant } }).then((result) => {
// TODO: Right now we invalidate everything but we will need to be more specific in the future
if (type === "mutation") invalidate(tenant.orgSlug, tenant.slug);
// if (type === "mutation") invalidate(tenant.orgSlug, tenant.slug);
return result;
}),
);
Expand Down
128 changes: 60 additions & 68 deletions apps/web/src/api/trpc/routers/org/billing.ts
Original file line number Diff line number Diff line change
@@ -1,77 +1,69 @@
import { TRPCError } from "@trpc/server";
import { eq } from "drizzle-orm";
import type Stripe from "stripe";
import { useStripe } from "~/api/stripe";
// import { useStripe } from "~/api/stripe";
import { organisations } from "~/db";
import { env } from "~/env";
import { createTRPCRouter, orgProcedure } from "../../helpers";

export const billingRouter = createTRPCRouter({
portalUrl: orgProcedure.mutation(async ({ ctx }) => {
const [org] = await ctx.db
.select({
name: organisations.name,
billingEmail: organisations.billingEmail,
stripeCustomerId: organisations.stripeCustomerId,
})
.from(organisations)
.where(eq(organisations.pk, ctx.org.pk));
if (!org)
throw new TRPCError({ code: "NOT_FOUND", message: "organisation" }); // TODO: Proper error code which the frontend knows how to handle

let customerId: string;
const stripe = await useStripe();

if (!org.stripeCustomerId) {
try {
const customer = await stripe.customers.create({
name: org.name,
email: org.billingEmail || undefined,
});

await ctx.db
.update(organisations)
.set({ stripeCustomerId: customer.id })
.where(eq(organisations.pk, ctx.org.pk));

customerId = customer.id;
} catch (err) {
console.error("Error creating customer", err);
throw new Error("Error creating customer");
}
} else {
customerId = org.stripeCustomerId;
}

// TODO: When using the official Stripe SDK, this endpoint causes the entire Edge Function to hang and i'm at a loss to why.
// TODO: This will do for now but we should try and fix it.

const body = new URLSearchParams({
customer: customerId,
return_url: `${env.VITE_PROD_ORIGIN}/o/${ctx.org.slug}/settings`,
});

const resp = await fetch(
"https://api.stripe.com/v1/billing_portal/sessions",
{
method: "POST",
headers: {
Authorization: `Bearer ${stripe.secret}`,
"Content-Type": "application/x-www-form-urlencoded",
},
body: body.toString(),
},
);
if (!resp.ok) {
const body = await resp.text();
console.error("Error creating billing portal session", resp.status, body);
throw new Error(
`Error creating billing portal session: '${resp.status}' '${body}'`,
);
}
const session: Stripe.Response<Stripe.BillingPortal.Session> =
await resp.json();

return session.url;
}),
// portalUrl: orgProcedure.mutation(async ({ ctx }) => {
// const [org] = await ctx.db
// .select({
// name: organisations.name,
// billingEmail: organisations.billingEmail,
// stripeCustomerId: organisations.stripeCustomerId,
// })
// .from(organisations)
// .where(eq(organisations.pk, ctx.org.pk));
// if (!org)
// throw new TRPCError({ code: "NOT_FOUND", message: "organisation" }); // TODO: Proper error code which the frontend knows how to handle
// let customerId: string;
// const stripe = await useStripe();
// if (!org.stripeCustomerId) {
// try {
// const customer = await stripe.customers.create({
// name: org.name,
// email: org.billingEmail || undefined,
// });
// await ctx.db
// .update(organisations)
// .set({ stripeCustomerId: customer.id })
// .where(eq(organisations.pk, ctx.org.pk));
// customerId = customer.id;
// } catch (err) {
// console.error("Error creating customer", err);
// throw new Error("Error creating customer");
// }
// } else {
// customerId = org.stripeCustomerId;
// }
// // TODO: When using the official Stripe SDK, this endpoint causes the entire Edge Function to hang and i'm at a loss to why.
// // TODO: This will do for now but we should try and fix it.
// const body = new URLSearchParams({
// customer: customerId,
// return_url: `${env.VITE_PROD_ORIGIN}/o/${ctx.org.slug}/settings`,
// });
// const resp = await fetch(
// "https://api.stripe.com/v1/billing_portal/sessions",
// {
// method: "POST",
// headers: {
// Authorization: `Bearer ${stripe.secret}`,
// "Content-Type": "application/x-www-form-urlencoded",
// },
// body: body.toString(),
// },
// );
// if (!resp.ok) {
// const body = await resp.text();
// console.error("Error creating billing portal session", resp.status, body);
// throw new Error(
// `Error creating billing portal session: '${resp.status}' '${body}'`,
// );
// }
// const session: Stripe.Response<Stripe.BillingPortal.Session> =
// await resp.json();
// return session.url;
// }),
});
3 changes: 1 addition & 2 deletions apps/web/src/api/trpc/routers/policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { union } from "drizzle-orm/mysql-core";
import { createAuditLog } from "~/api/auditLog";
import { withTenant } from "~/api/tenant";
import { omit } from "~/api/utils";
import { invalidate } from "~/api/utils/realtime";
import { createTransaction } from "~/api/utils/transaction";
import {
GroupMemberVariants,
Expand Down Expand Up @@ -45,7 +44,7 @@ const policyProcedure = authedProcedure
return withTenant(tenant, () =>
next({ ctx: { policy, tenant } }).then((result) => {
// TODO: Right now we invalidate everything but we will need to be more specific in the future
if (type === "mutation") invalidate(tenant.orgSlug, tenant.slug);
// if (type === "mutation") invalidate(tenant.orgSlug, tenant.slug);
return result;
}),
);
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/api/trpc/routers/tenant/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ export const tenantRouter = createTRPCRouter({

const cfg = mobilityConfig.find(
(r: any) =>
r.discoveryUrl === `${env.MDM_URL}/EnrollmentServer/Discovery.svc`,
r.discoveryUrl === `${env.MANAGE_URL}/EnrollmentServer/Discovery.svc`,
);

const result = !cfg
Expand Down
Loading

0 comments on commit 88d7798

Please sign in to comment.