Compare commits
67 Commits
fix/securi
...
fa26764764
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa26764764 | ||
|
|
b3a1c3b252 | ||
|
|
2991535624 | ||
|
|
8fc01e07cb | ||
|
|
53c08cd56a | ||
|
|
27854fc6e8 | ||
|
|
be808bcece | ||
|
|
fd774c4a9e | ||
|
|
a25b576ccf | ||
|
|
6212756b54 | ||
|
|
6b3a02a092 | ||
|
|
25ae2da426 | ||
|
|
aabb06e520 | ||
|
|
457d4e47f9 | ||
|
|
ab47891a09 | ||
|
|
d7b683d7bd | ||
|
|
d1626aa1b6 | ||
|
|
5b86247e98 | ||
|
|
04425c9607 | ||
|
|
1c3014123f | ||
|
|
1494bae703 | ||
|
|
5e7534d273 | ||
|
|
550bd71e33 | ||
|
|
3f6afc05f8 | ||
|
|
1a9d1f6a0f | ||
|
|
1e5a9e72e6 | ||
|
|
624c1c2ac2 | ||
|
|
deaa005b32 | ||
|
|
ceede6d267 | ||
|
|
6948a63e07 | ||
|
|
b6be184fbd | ||
|
|
0897c9d5ef | ||
|
|
6b5256978e | ||
|
|
ddf0cc5517 | ||
|
|
d2cef0cdae | ||
|
|
237f9166f4 | ||
|
|
82ed2ef987 | ||
|
|
4ef751509a | ||
|
|
b27cdaeb27 | ||
|
|
9036e9f32f | ||
|
|
dbc2501d4c | ||
|
|
10b671531b | ||
|
|
9f763e3f1e | ||
|
|
bf70ea1671 | ||
|
|
d71b9a27c9 | ||
|
|
c352d8ff64 | ||
|
|
a264c24f26 | ||
|
|
9bc70078c2 | ||
|
|
956ccede2d | ||
|
|
f435173566 | ||
|
|
26b24bdd50 | ||
|
|
287faa4570 | ||
|
|
3dd98d137e | ||
|
|
4bdb9fe1f7 | ||
|
|
5434e409fa | ||
|
|
f25aee39d9 | ||
|
|
f30769d73a | ||
|
|
334a55f0a0 | ||
|
|
f7e18400de | ||
|
|
ba29257ba5 | ||
|
|
b927d89e49 | ||
|
|
5ce7934289 | ||
|
|
35e027c917 | ||
|
|
94305797dc | ||
|
|
37612dd001 | ||
|
|
758a84b20e | ||
|
|
909c22dc45 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -29,7 +29,6 @@ npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
firebase-debug.log*
|
||||
|
||||
# env files (can opt-in for committing if needed)
|
||||
.env*
|
||||
|
||||
14
firebase-debug.log
Normal file
14
firebase-debug.log
Normal file
@@ -0,0 +1,14 @@
|
||||
[debug] [2026-01-23T19:18:31.890Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
||||
[debug] [2026-01-23T19:18:31.892Z] > authorizing via signed-in user (ppradeepd@gmail.com)
|
||||
[debug] [2026-01-23T19:18:31.892Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
||||
[debug] [2026-01-23T19:18:31.892Z] > authorizing via signed-in user (ppradeepd@gmail.com)
|
||||
[debug] [2026-01-23T19:18:31.901Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
||||
[debug] [2026-01-23T19:18:31.902Z] > authorizing via signed-in user (ppradeepd@gmail.com)
|
||||
[debug] [2026-01-23T19:18:32.021Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
||||
[debug] [2026-01-23T19:18:32.021Z] > authorizing via signed-in user (ppradeepd@gmail.com)
|
||||
[debug] [2026-01-23T19:18:32.022Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
||||
[debug] [2026-01-23T19:18:32.022Z] > authorizing via signed-in user (ppradeepd@gmail.com)
|
||||
[debug] [2026-01-23T19:18:32.057Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
||||
[debug] [2026-01-23T19:18:32.057Z] > authorizing via signed-in user (ppradeepd@gmail.com)
|
||||
[debug] [2026-01-23T19:18:32.058Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
||||
[debug] [2026-01-23T19:18:32.058Z] > authorizing via signed-in user (ppradeepd@gmail.com)
|
||||
@@ -7,9 +7,10 @@ const nextConfig: NextConfig = {
|
||||
// Image optimization
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{ protocol: "https", hostname: "*.contabostorage.com" },
|
||||
{ protocol: "https", hostname: "*.amazonaws.com" },
|
||||
{ protocol: "https", hostname: "*.digitaloceanspaces.com" },
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "**",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -39,6 +39,7 @@ export default function UserDetailPage() {
|
||||
const [verificationHistory, setVerificationHistory] = useState<VerificationHistoryEntry[]>([]);
|
||||
const [agentFieldValues, setAgentFieldValues] = useState<AgentFieldValue[]>([]);
|
||||
const [isTogglingStatus, setIsTogglingStatus] = useState(false);
|
||||
const [pendingApprovalConfirm, setPendingApprovalConfirm] = useState(false);
|
||||
|
||||
// Is the agent subscription active (paid)?
|
||||
const PAID_STATUSES = new Set(['ACTIVE', 'TRIALING', 'PAST_DUE']);
|
||||
@@ -188,9 +189,23 @@ export default function UserDetailPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleVerification = async (status: VerificationStatus) => {
|
||||
const handleVerification = async (
|
||||
status: VerificationStatus,
|
||||
opts?: { skipPaymentCheck?: boolean },
|
||||
) => {
|
||||
if (!user) return;
|
||||
|
||||
// Guard: approving a user without active subscription requires extra confirmation
|
||||
if (
|
||||
status === 'APPROVED' &&
|
||||
!opts?.skipPaymentCheck &&
|
||||
!isSubscriptionActive(user.agentProfile?.subscriptionStatus)
|
||||
) {
|
||||
setPendingApprovalConfirm(true);
|
||||
return;
|
||||
}
|
||||
|
||||
setPendingApprovalConfirm(false);
|
||||
setIsUpdatingVerification(true);
|
||||
setError('');
|
||||
setUpdateSuccess('');
|
||||
@@ -834,6 +849,44 @@ export default function UserDetailPage() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Approve-without-payment confirmation modal */}
|
||||
{pendingApprovalConfirm && (
|
||||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
||||
<div className="bg-white rounded-lg shadow-xl max-w-md w-full mx-4">
|
||||
<div className="px-6 py-4 border-b border-gray-200">
|
||||
<h3 className="text-lg font-semibold text-gray-900">Approve Without Payment?</h3>
|
||||
</div>
|
||||
<div className="px-6 py-4 space-y-3">
|
||||
<p className="text-sm text-gray-700">
|
||||
This user has <span className="font-semibold text-red-700">not paid</span> for a subscription.
|
||||
</p>
|
||||
<p className="text-sm text-gray-600">
|
||||
Approving will mark the profile as verified and it will be visible in
|
||||
public search results. Payment is not required for visibility.
|
||||
</p>
|
||||
<p className="text-sm text-gray-600">
|
||||
Are you sure you want to approve this profile anyway?
|
||||
</p>
|
||||
</div>
|
||||
<div className="px-6 py-4 border-t border-gray-200 flex justify-end space-x-3">
|
||||
<button
|
||||
onClick={() => setPendingApprovalConfirm(false)}
|
||||
disabled={isUpdatingVerification}
|
||||
className="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors disabled:opacity-50"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleVerification('APPROVED', { skipPaymentCheck: true })}
|
||||
disabled={isUpdatingVerification}
|
||||
className="px-4 py-2 bg-yellow-600 hover:bg-yellow-700 text-white rounded-lg transition-colors disabled:opacity-50"
|
||||
>
|
||||
{isUpdatingVerification ? 'Approving...' : 'Approve Anyway'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user