Spaces:
Sleeping
Sleeping
Merge branch 'main' of https://huggingface.co/spaces/gaurv007/ClauseGuard
Browse files- DEPLOY.md +2 -2
- api/main.py +1 -1
- extension/background.js +3 -3
- extension/manifest.json +2 -2
- extension/popup.html +4 -4
- extension/popup.js +1 -1
- web/app/api/emails/scan-report/route.ts +3 -3
- web/app/api/emails/welcome/route.ts +3 -3
- web/app/api/webhooks/razorpay/route.ts +3 -3
- web/app/layout.tsx +1 -1
- web/app/page.tsx +2 -2
- web/app/privacy/page.tsx +1 -1
- web/app/terms/page.tsx +1 -1
DEPLOY.md
CHANGED
|
@@ -150,7 +150,7 @@ CLAUSEGUARD_API_URL=https://your-backend-url.com
|
|
| 150 |
6. Your site will be at: `https://clauseguard.vercel.app`
|
| 151 |
|
| 152 |
### Custom domain:
|
| 153 |
-
- In Vercel → Settings → Domains → Add `
|
| 154 |
- Point your DNS A record to Vercel's IP
|
| 155 |
|
| 156 |
---
|
|
@@ -187,7 +187,7 @@ CLAUSEGUARD_API_URL=https://your-backend-url.com
|
|
| 187 |
|
| 188 |
1. Go to https://resend.com → Sign up
|
| 189 |
2. API Keys → Create → Copy key → `RESEND_API_KEY`
|
| 190 |
-
3. Domains → Add `
|
| 191 |
4. Until domain is verified, emails send from `onboarding@resend.dev`
|
| 192 |
|
| 193 |
---
|
|
|
|
| 150 |
6. Your site will be at: `https://clauseguard.vercel.app`
|
| 151 |
|
| 152 |
### Custom domain:
|
| 153 |
+
- In Vercel → Settings → Domains → Add `clauseguardweb.netlify.app`
|
| 154 |
- Point your DNS A record to Vercel's IP
|
| 155 |
|
| 156 |
---
|
|
|
|
| 187 |
|
| 188 |
1. Go to https://resend.com → Sign up
|
| 189 |
2. API Keys → Create → Copy key → `RESEND_API_KEY`
|
| 190 |
+
3. Domains → Add `clauseguardweb.netlify.app` → Add DNS records they give you
|
| 191 |
4. Until domain is verified, emails send from `onboarding@resend.dev`
|
| 192 |
|
| 193 |
---
|
api/main.py
CHANGED
|
@@ -173,7 +173,7 @@ app = FastAPI(title="ClauseGuard API", version="1.0.0", lifespan=lifespan)
|
|
| 173 |
|
| 174 |
app.add_middleware(
|
| 175 |
CORSMiddleware,
|
| 176 |
-
allow_origins=["https://
|
| 177 |
allow_credentials=True, allow_methods=["*"], allow_headers=["*"],
|
| 178 |
)
|
| 179 |
|
|
|
|
| 173 |
|
| 174 |
app.add_middleware(
|
| 175 |
CORSMiddleware,
|
| 176 |
+
allow_origins=["https://clauseguardweb.netlify.app", "https://clauseguardweb.netlify.app", "chrome-extension://*", "http://localhost:3000"],
|
| 177 |
allow_credentials=True, allow_methods=["*"], allow_headers=["*"],
|
| 178 |
)
|
| 179 |
|
extension/background.js
CHANGED
|
@@ -10,8 +10,8 @@ const API_TIMEOUT_MS = 45000;
|
|
| 10 |
|
| 11 |
// Website URLs (for auth detection)
|
| 12 |
const SITE_ORIGINS = [
|
| 13 |
-
"https://
|
| 14 |
-
"https://
|
| 15 |
];
|
| 16 |
// Add your Netlify URL here after deploy:
|
| 17 |
// SITE_ORIGINS.push("https://your-site.netlify.app");
|
|
@@ -50,7 +50,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
| 50 |
|
| 51 |
// ─── External messages from website ───
|
| 52 |
chrome.runtime.onMessageExternal.addListener((message, sender, sendResponse) => {
|
| 53 |
-
// Accept from any allowed origin (
|
| 54 |
const handle = async () => {
|
| 55 |
switch (message.type) {
|
| 56 |
case "SET_AUTH": {
|
|
|
|
| 10 |
|
| 11 |
// Website URLs (for auth detection)
|
| 12 |
const SITE_ORIGINS = [
|
| 13 |
+
"https://clauseguardweb.netlify.app",
|
| 14 |
+
"https://clauseguardweb.netlify.app",
|
| 15 |
];
|
| 16 |
// Add your Netlify URL here after deploy:
|
| 17 |
// SITE_ORIGINS.push("https://your-site.netlify.app");
|
|
|
|
| 50 |
|
| 51 |
// ─── External messages from website ───
|
| 52 |
chrome.runtime.onMessageExternal.addListener((message, sender, sendResponse) => {
|
| 53 |
+
// Accept from any allowed origin (clauseguardweb.netlify.app, netlify, localhost)
|
| 54 |
const handle = async () => {
|
| 55 |
switch (message.type) {
|
| 56 |
case "SET_AUTH": {
|
extension/manifest.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
| 12 |
],
|
| 13 |
"host_permissions": [
|
| 14 |
"https://gaurv007-clauseguard-api.hf.space/*",
|
| 15 |
-
"https://
|
| 16 |
"https://*.netlify.app/*"
|
| 17 |
],
|
| 18 |
"background": {
|
|
@@ -40,7 +40,7 @@
|
|
| 40 |
],
|
| 41 |
"externally_connectable": {
|
| 42 |
"matches": [
|
| 43 |
-
"https://
|
| 44 |
"https://*.netlify.app/*",
|
| 45 |
"http://localhost:3000/*"
|
| 46 |
]
|
|
|
|
| 12 |
],
|
| 13 |
"host_permissions": [
|
| 14 |
"https://gaurv007-clauseguard-api.hf.space/*",
|
| 15 |
+
"https://clauseguardweb.netlify.app/*",
|
| 16 |
"https://*.netlify.app/*"
|
| 17 |
],
|
| 18 |
"background": {
|
|
|
|
| 40 |
],
|
| 41 |
"externally_connectable": {
|
| 42 |
"matches": [
|
| 43 |
+
"https://clauseguardweb.netlify.app/*",
|
| 44 |
"https://*.netlify.app/*",
|
| 45 |
"http://localhost:3000/*"
|
| 46 |
]
|
extension/popup.html
CHANGED
|
@@ -95,7 +95,7 @@
|
|
| 95 |
<div id="limit-banner" class="limit-banner">
|
| 96 |
<p class="limit-title">Free limit reached</p>
|
| 97 |
<p>Upgrade for unlimited scans.</p>
|
| 98 |
-
<a href="https://
|
| 99 |
</div>
|
| 100 |
|
| 101 |
<div id="results-view" style="display:none;">
|
|
@@ -140,9 +140,9 @@
|
|
| 140 |
</div>
|
| 141 |
|
| 142 |
<div class="footer">
|
| 143 |
-
<a href="https://
|
| 144 |
-
<a href="https://
|
| 145 |
-
<a href="https://
|
| 146 |
</div>
|
| 147 |
|
| 148 |
<script src="popup.js"></script>
|
|
|
|
| 95 |
<div id="limit-banner" class="limit-banner">
|
| 96 |
<p class="limit-title">Free limit reached</p>
|
| 97 |
<p>Upgrade for unlimited scans.</p>
|
| 98 |
+
<a href="https://clauseguardweb.netlify.app/#pricing" target="_blank" class="btn-upgrade">View plans</a>
|
| 99 |
</div>
|
| 100 |
|
| 101 |
<div id="results-view" style="display:none;">
|
|
|
|
| 140 |
</div>
|
| 141 |
|
| 142 |
<div class="footer">
|
| 143 |
+
<a href="https://clauseguardweb.netlify.app" target="_blank">clauseguardweb.netlify.app</a>
|
| 144 |
+
<a href="https://clauseguardweb.netlify.app/dashboard-pages/dashboard" target="_blank">Dashboard</a>
|
| 145 |
+
<a href="https://clauseguardweb.netlify.app/#pricing" target="_blank">Upgrade</a>
|
| 146 |
</div>
|
| 147 |
|
| 148 |
<script src="popup.js"></script>
|
extension/popup.js
CHANGED
|
@@ -87,7 +87,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
| 87 |
// Login button
|
| 88 |
const btnLogin = document.getElementById("btn-login");
|
| 89 |
if (btnLogin) btnLogin.addEventListener("click", () => {
|
| 90 |
-
chrome.tabs.create({ url: "https://
|
| 91 |
});
|
| 92 |
});
|
| 93 |
|
|
|
|
| 87 |
// Login button
|
| 88 |
const btnLogin = document.getElementById("btn-login");
|
| 89 |
if (btnLogin) btnLogin.addEventListener("click", () => {
|
| 90 |
+
chrome.tabs.create({ url: "https://clauseguardweb.netlify.app/auth/login" }); // Update with your actual URL
|
| 91 |
});
|
| 92 |
});
|
| 93 |
|
web/app/api/emails/scan-report/route.ts
CHANGED
|
@@ -15,7 +15,7 @@ export async function POST(req: NextRequest) {
|
|
| 15 |
const gradeBg = grade === "F" || grade === "D" ? "#fef2f2" : grade === "C" ? "#fffbeb" : "#f0fdf4";
|
| 16 |
|
| 17 |
const { data, error } = await resend.emails.send({
|
| 18 |
-
from: "ClauseGuard <reports@
|
| 19 |
to: [email],
|
| 20 |
subject: `Scan complete — Grade ${grade} (${risk_score}/100 risk)`,
|
| 21 |
html: `
|
|
@@ -35,13 +35,13 @@ export async function POST(req: NextRequest) {
|
|
| 35 |
</div>
|
| 36 |
</div>
|
| 37 |
|
| 38 |
-
<a href="https://
|
| 39 |
style="display:inline-block;background:#18181b;color:#fff;padding:10px 20px;border-radius:6px;text-decoration:none;font-size:14px;font-weight:500;">
|
| 40 |
View full report
|
| 41 |
</a>
|
| 42 |
|
| 43 |
<p style="font-size:12px;color:#a1a1aa;margin-top:32px;border-top:1px solid #f4f4f5;padding-top:16px;">
|
| 44 |
-
|
| 45 |
</p>
|
| 46 |
</div>
|
| 47 |
`,
|
|
|
|
| 15 |
const gradeBg = grade === "F" || grade === "D" ? "#fef2f2" : grade === "C" ? "#fffbeb" : "#f0fdf4";
|
| 16 |
|
| 17 |
const { data, error } = await resend.emails.send({
|
| 18 |
+
from: "ClauseGuard <reports@clauseguardweb.netlify.app>",
|
| 19 |
to: [email],
|
| 20 |
subject: `Scan complete — Grade ${grade} (${risk_score}/100 risk)`,
|
| 21 |
html: `
|
|
|
|
| 35 |
</div>
|
| 36 |
</div>
|
| 37 |
|
| 38 |
+
<a href="https://clauseguardweb.netlify.app/dashboard-pages/dashboard"
|
| 39 |
style="display:inline-block;background:#18181b;color:#fff;padding:10px 20px;border-radius:6px;text-decoration:none;font-size:14px;font-weight:500;">
|
| 40 |
View full report
|
| 41 |
</a>
|
| 42 |
|
| 43 |
<p style="font-size:12px;color:#a1a1aa;margin-top:32px;border-top:1px solid #f4f4f5;padding-top:16px;">
|
| 44 |
+
clauseguardweb.netlify.app — Not legal advice.
|
| 45 |
</p>
|
| 46 |
</div>
|
| 47 |
`,
|
web/app/api/emails/welcome/route.ts
CHANGED
|
@@ -12,7 +12,7 @@ export async function POST(req: NextRequest) {
|
|
| 12 |
}
|
| 13 |
|
| 14 |
const { data, error } = await resend.emails.send({
|
| 15 |
-
from: "ClauseGuard <welcome@
|
| 16 |
to: [email],
|
| 17 |
subject: "Welcome to ClauseGuard",
|
| 18 |
html: `
|
|
@@ -26,12 +26,12 @@ export async function POST(req: NextRequest) {
|
|
| 26 |
<li>Use the web scanner to paste and analyze any document</li>
|
| 27 |
<li>Get a risk score and grade for every Terms of Service you encounter</li>
|
| 28 |
</ul>
|
| 29 |
-
<a href="https://
|
| 30 |
style="display:inline-block;background:#18181b;color:#fff;padding:10px 20px;border-radius:6px;text-decoration:none;font-size:14px;font-weight:500;">
|
| 31 |
Scan your first document
|
| 32 |
</a>
|
| 33 |
<p style="font-size:12px;color:#a1a1aa;margin-top:32px;border-top:1px solid #f4f4f5;padding-top:16px;">
|
| 34 |
-
You are receiving this because you signed up at
|
| 35 |
</p>
|
| 36 |
</div>
|
| 37 |
`,
|
|
|
|
| 12 |
}
|
| 13 |
|
| 14 |
const { data, error } = await resend.emails.send({
|
| 15 |
+
from: "ClauseGuard <welcome@clauseguardweb.netlify.app>",
|
| 16 |
to: [email],
|
| 17 |
subject: "Welcome to ClauseGuard",
|
| 18 |
html: `
|
|
|
|
| 26 |
<li>Use the web scanner to paste and analyze any document</li>
|
| 27 |
<li>Get a risk score and grade for every Terms of Service you encounter</li>
|
| 28 |
</ul>
|
| 29 |
+
<a href="https://clauseguardweb.netlify.app/dashboard-pages/analyze"
|
| 30 |
style="display:inline-block;background:#18181b;color:#fff;padding:10px 20px;border-radius:6px;text-decoration:none;font-size:14px;font-weight:500;">
|
| 31 |
Scan your first document
|
| 32 |
</a>
|
| 33 |
<p style="font-size:12px;color:#a1a1aa;margin-top:32px;border-top:1px solid #f4f4f5;padding-top:16px;">
|
| 34 |
+
You are receiving this because you signed up at clauseguardweb.netlify.app.
|
| 35 |
</p>
|
| 36 |
</div>
|
| 37 |
`,
|
web/app/api/webhooks/razorpay/route.ts
CHANGED
|
@@ -47,10 +47,10 @@ export async function POST(req: NextRequest) {
|
|
| 47 |
// Send welcome email
|
| 48 |
if (data?.email && resend) {
|
| 49 |
await resend.emails.send({
|
| 50 |
-
from: "ClauseGuard <noreply@
|
| 51 |
to: [data.email],
|
| 52 |
subject: `Welcome to ClauseGuard ${plan.charAt(0).toUpperCase() + plan.slice(1)}`,
|
| 53 |
-
html: `<p>Your ${plan} subscription is active. You now have unlimited scans.</p><p><a href="https://
|
| 54 |
});
|
| 55 |
}
|
| 56 |
}
|
|
@@ -93,7 +93,7 @@ export async function POST(req: NextRequest) {
|
|
| 93 |
|
| 94 |
if (data?.email && resend) {
|
| 95 |
await resend.emails.send({
|
| 96 |
-
from: "ClauseGuard <noreply@
|
| 97 |
to: [data.email],
|
| 98 |
subject: "Payment failed — subscription paused",
|
| 99 |
html: "<p>Your payment failed and your subscription has been paused. Please update your payment method to continue.</p>",
|
|
|
|
| 47 |
// Send welcome email
|
| 48 |
if (data?.email && resend) {
|
| 49 |
await resend.emails.send({
|
| 50 |
+
from: "ClauseGuard <noreply@clauseguardweb.netlify.app>",
|
| 51 |
to: [data.email],
|
| 52 |
subject: `Welcome to ClauseGuard ${plan.charAt(0).toUpperCase() + plan.slice(1)}`,
|
| 53 |
+
html: `<p>Your ${plan} subscription is active. You now have unlimited scans.</p><p><a href="https://clauseguardweb.netlify.app/dashboard-pages/dashboard">Go to dashboard</a></p>`,
|
| 54 |
});
|
| 55 |
}
|
| 56 |
}
|
|
|
|
| 93 |
|
| 94 |
if (data?.email && resend) {
|
| 95 |
await resend.emails.send({
|
| 96 |
+
from: "ClauseGuard <noreply@clauseguardweb.netlify.app>",
|
| 97 |
to: [data.email],
|
| 98 |
subject: "Payment failed — subscription paused",
|
| 99 |
html: "<p>Your payment failed and your subscription has been paused. Please update your payment method to continue.</p>",
|
web/app/layout.tsx
CHANGED
|
@@ -10,7 +10,7 @@ export const metadata: Metadata = {
|
|
| 10 |
openGraph: {
|
| 11 |
title: "ClauseGuard",
|
| 12 |
description: "Know what you are agreeing to.",
|
| 13 |
-
url: "https://
|
| 14 |
siteName: "ClauseGuard",
|
| 15 |
type: "website",
|
| 16 |
},
|
|
|
|
| 10 |
openGraph: {
|
| 11 |
title: "ClauseGuard",
|
| 12 |
description: "Know what you are agreeing to.",
|
| 13 |
+
url: "https://clauseguardweb.netlify.app",
|
| 14 |
siteName: "ClauseGuard",
|
| 15 |
type: "website",
|
| 16 |
},
|
web/app/page.tsx
CHANGED
|
@@ -154,7 +154,7 @@ export default function Home() {
|
|
| 154 |
</li>
|
| 155 |
))}
|
| 156 |
</ul>
|
| 157 |
-
<Link href={plan.name === "Free" ? "/auth/signup" : plan.name === "Team" ? "mailto:hello@
|
| 158 |
className={`mt-6 block w-full py-2.5 rounded-lg text-[13px] font-medium text-center transition-colors ${
|
| 159 |
plan.highlight
|
| 160 |
? "bg-zinc-900 text-white hover:bg-zinc-800"
|
|
@@ -195,7 +195,7 @@ export default function Home() {
|
|
| 195 |
<div className="flex gap-5 text-[13px] text-zinc-400">
|
| 196 |
<Link href="/privacy" className="hover:text-zinc-600">Privacy</Link>
|
| 197 |
<Link href="/terms" className="hover:text-zinc-600">Terms</Link>
|
| 198 |
-
<a href="mailto:hello@
|
| 199 |
</div>
|
| 200 |
</div>
|
| 201 |
</footer>
|
|
|
|
| 154 |
</li>
|
| 155 |
))}
|
| 156 |
</ul>
|
| 157 |
+
<Link href={plan.name === "Free" ? "/auth/signup" : plan.name === "Team" ? "mailto:hello@clauseguardweb.netlify.app" : "/auth/signup"}
|
| 158 |
className={`mt-6 block w-full py-2.5 rounded-lg text-[13px] font-medium text-center transition-colors ${
|
| 159 |
plan.highlight
|
| 160 |
? "bg-zinc-900 text-white hover:bg-zinc-800"
|
|
|
|
| 195 |
<div className="flex gap-5 text-[13px] text-zinc-400">
|
| 196 |
<Link href="/privacy" className="hover:text-zinc-600">Privacy</Link>
|
| 197 |
<Link href="/terms" className="hover:text-zinc-600">Terms</Link>
|
| 198 |
+
<a href="mailto:hello@clauseguardweb.netlify.app" className="hover:text-zinc-600">Contact</a>
|
| 199 |
</div>
|
| 200 |
</div>
|
| 201 |
</footer>
|
web/app/privacy/page.tsx
CHANGED
|
@@ -49,7 +49,7 @@ export default function PrivacyPage() {
|
|
| 49 |
|
| 50 |
<section>
|
| 51 |
<h2 className="text-base font-medium text-zinc-900 mb-2">Contact</h2>
|
| 52 |
-
<p>Questions about this policy: <a href="mailto:privacy@
|
| 53 |
</section>
|
| 54 |
</div>
|
| 55 |
</div>
|
|
|
|
| 49 |
|
| 50 |
<section>
|
| 51 |
<h2 className="text-base font-medium text-zinc-900 mb-2">Contact</h2>
|
| 52 |
+
<p>Questions about this policy: <a href="mailto:privacy@clauseguardweb.netlify.app" className="text-zinc-900 underline">privacy@clauseguardweb.netlify.app</a></p>
|
| 53 |
</section>
|
| 54 |
</div>
|
| 55 |
</div>
|
web/app/terms/page.tsx
CHANGED
|
@@ -42,7 +42,7 @@ export default function TermsPage() {
|
|
| 42 |
|
| 43 |
<section>
|
| 44 |
<h2 className="text-base font-medium text-zinc-900 mb-2">Contact</h2>
|
| 45 |
-
<p>Questions: <a href="mailto:legal@
|
| 46 |
</section>
|
| 47 |
</div>
|
| 48 |
</div>
|
|
|
|
| 42 |
|
| 43 |
<section>
|
| 44 |
<h2 className="text-base font-medium text-zinc-900 mb-2">Contact</h2>
|
| 45 |
+
<p>Questions: <a href="mailto:legal@clauseguardweb.netlify.app" className="text-zinc-900 underline">legal@clauseguardweb.netlify.app</a></p>
|
| 46 |
</section>
|
| 47 |
</div>
|
| 48 |
</div>
|