remove public tags and validate current password

This commit is contained in:
chark1es 2025-03-08 22:00:00 -08:00
parent e36b5ee0ad
commit 16d9ec9e1d
4 changed files with 99 additions and 28 deletions

View file

@ -25,20 +25,18 @@ export default defineConfig({
// Define environment variables that should be available to client components // Define environment variables that should be available to client components
vite: { vite: {
define: { define: {
"import.meta.env.PUBLIC_LOGTO_APP_ID": JSON.stringify( "import.meta.env.LOGTO_APP_ID": JSON.stringify(process.env.LOGTO_APP_ID),
process.env.PUBLIC_LOGTO_APP_ID, "import.meta.env.LOGTO_APP_SECRET": JSON.stringify(
process.env.LOGTO_APP_SECRET,
), ),
"import.meta.env.PUBLIC_LOGTO_APP_SECRET": JSON.stringify( "import.meta.env.LOGTO_ENDPOINT": JSON.stringify(
process.env.PUBLIC_LOGTO_APP_SECRET, process.env.LOGTO_ENDPOINT,
), ),
"import.meta.env.PUBLIC_LOGTO_ENDPOINT": JSON.stringify( "import.meta.env.LOGTO_TOKEN_ENDPOINT": JSON.stringify(
process.env.PUBLIC_LOGTO_ENDPOINT, process.env.LOGTO_TOKEN_ENDPOINT,
), ),
"import.meta.env.PUBLIC_LOGTO_TOKEN_ENDPOINT": JSON.stringify( "import.meta.env.LOGTO_API_ENDPOINT": JSON.stringify(
process.env.PUBLIC_LOGTO_TOKEN_ENDPOINT, process.env.LOGTO_API_ENDPOINT,
),
"import.meta.env.PUBLIC_LOGTO_API_ENDPOINT": JSON.stringify(
process.env.PUBLIC_LOGTO_API_ENDPOINT,
), ),
}, },
}, },

View file

@ -32,11 +32,11 @@ export default function PasswordChangeSettings({
const [debugInfo, setDebugInfo] = useState<any>(null); const [debugInfo, setDebugInfo] = useState<any>(null);
// Access environment variables directly // Access environment variables directly
const envLogtoAppId = import.meta.env.PUBLIC_LOGTO_APP_ID; const envLogtoAppId = import.meta.env.LOGTO_APP_ID;
const envLogtoAppSecret = import.meta.env.PUBLIC_LOGTO_APP_SECRET; const envLogtoAppSecret = import.meta.env.LOGTO_APP_SECRET;
const envLogtoEndpoint = import.meta.env.PUBLIC_LOGTO_ENDPOINT; const envLogtoEndpoint = import.meta.env.LOGTO_ENDPOINT;
const envLogtoTokenEndpoint = import.meta.env.PUBLIC_LOGTO_TOKEN_ENDPOINT; const envLogtoTokenEndpoint = import.meta.env.LOGTO_TOKEN_ENDPOINT;
const envLogtoApiEndpoint = import.meta.env.PUBLIC_LOGTO_API_ENDPOINT; const envLogtoApiEndpoint = import.meta.env.LOGTO_API_ENDPOINT;
// Use environment variables or props (fallback) // Use environment variables or props (fallback)
const logtoAppId = envLogtoAppId || propLogtoAppId; const logtoAppId = envLogtoAppId || propLogtoAppId;
@ -53,11 +53,11 @@ export default function PasswordChangeSettings({
console.log("Props - logtoEndpoint:", propLogtoEndpoint); console.log("Props - logtoEndpoint:", propLogtoEndpoint);
console.log("Props - logtoTokenEndpoint:", propLogtoTokenEndpoint); console.log("Props - logtoTokenEndpoint:", propLogtoTokenEndpoint);
console.log("Props - logtoApiEndpoint:", propLogtoApiEndpoint); console.log("Props - logtoApiEndpoint:", propLogtoApiEndpoint);
console.log("Env - PUBLIC_LOGTO_APP_ID:", envLogtoAppId); console.log("Env - LOGTO_APP_ID:", envLogtoAppId);
console.log("Env - PUBLIC_LOGTO_APP_SECRET:", envLogtoAppSecret); console.log("Env - LOGTO_APP_SECRET:", envLogtoAppSecret);
console.log("Env - PUBLIC_LOGTO_ENDPOINT:", envLogtoEndpoint); console.log("Env - LOGTO_ENDPOINT:", envLogtoEndpoint);
console.log("Env - PUBLIC_LOGTO_TOKEN_ENDPOINT:", envLogtoTokenEndpoint); console.log("Env - LOGTO_TOKEN_ENDPOINT:", envLogtoTokenEndpoint);
console.log("Env - PUBLIC_LOGTO_API_ENDPOINT:", envLogtoApiEndpoint); console.log("Env - LOGTO_API_ENDPOINT:", envLogtoApiEndpoint);
console.log("Using - logtoAppId:", logtoAppId); console.log("Using - logtoAppId:", logtoAppId);
console.log("Using - logtoAppSecret:", logtoAppSecret); console.log("Using - logtoAppSecret:", logtoAppSecret);
console.log("Using - logtoEndpoint:", logtoEndpoint); console.log("Using - logtoEndpoint:", logtoEndpoint);
@ -328,6 +328,7 @@ export default function PasswordChangeSettings({
// Prepare request data with explicit values (not relying on variable references that might be undefined) // Prepare request data with explicit values (not relying on variable references that might be undefined)
const requestData = { const requestData = {
userId: logtoUserId, userId: logtoUserId,
currentPassword: formData.currentPassword,
newPassword: formData.newPassword, newPassword: formData.newPassword,
logtoAppId: logtoAppId || "", logtoAppId: logtoAppId || "",
logtoAppSecret: logtoAppSecret || "", logtoAppSecret: logtoAppSecret || "",
@ -337,6 +338,7 @@ export default function PasswordChangeSettings({
console.log("Request data:", { console.log("Request data:", {
...requestData, ...requestData,
currentPassword: "[REDACTED]",
newPassword: "[REDACTED]", newPassword: "[REDACTED]",
logtoAppSecret: "[REDACTED]" logtoAppSecret: "[REDACTED]"
}); });
@ -471,10 +473,10 @@ export default function PasswordChangeSettings({
console.log("Debug Info:"); console.log("Debug Info:");
console.log("- logtoUserId:", logtoUserId); console.log("- logtoUserId:", logtoUserId);
console.log("- Environment Variables:"); console.log("- Environment Variables:");
console.log(" - PUBLIC_LOGTO_APP_ID:", import.meta.env.PUBLIC_LOGTO_APP_ID); console.log(" - LOGTO_APP_ID:", import.meta.env.LOGTO_APP_ID);
console.log(" - PUBLIC_LOGTO_ENDPOINT:", import.meta.env.PUBLIC_LOGTO_ENDPOINT); console.log(" - LOGTO_ENDPOINT:", import.meta.env.LOGTO_ENDPOINT);
console.log(" - PUBLIC_LOGTO_TOKEN_ENDPOINT:", import.meta.env.PUBLIC_LOGTO_TOKEN_ENDPOINT); console.log(" - LOGTO_TOKEN_ENDPOINT:", import.meta.env.LOGTO_TOKEN_ENDPOINT);
console.log(" - PUBLIC_LOGTO_API_ENDPOINT:", import.meta.env.PUBLIC_LOGTO_API_ENDPOINT); console.log(" - LOGTO_API_ENDPOINT:", import.meta.env.LOGTO_API_ENDPOINT);
toast.success("Debug info logged to console"); toast.success("Debug info logged to console");
}} }}

View file

@ -1,5 +1,5 @@
import PocketBase from 'pocketbase'; import PocketBase from "pocketbase";
const pb = new PocketBase(import.meta.env.PUBLIC_POCKETBASE_URL); const pb = new PocketBase(import.meta.env.POCKETBASE_URL);
export default pb; export default pb;

View file

@ -51,6 +51,54 @@ async function getLogtoAccessToken(
} }
} }
// Helper function to verify user's current password
async function verifyUserPassword(
logtoApiEndpoint: string,
userId: string,
currentPassword: string,
accessToken: string,
): Promise<boolean> {
try {
console.log("Verifying current password");
const response = await fetch(
`${logtoApiEndpoint}/api/users/${userId}/password/verify`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({ password: currentPassword }),
},
);
// 204 means password matches, 422 means it doesn't match
if (response.status === 204) {
console.log("Current password verified successfully");
return true;
}
if (response.status === 422) {
console.error(
"Current password verification failed: Password does not match",
);
return false;
}
const errorText = await response.text();
console.error("Password verification error:", {
status: response.status,
statusText: response.statusText,
body: errorText,
});
return false;
} catch (error) {
console.error("Error verifying password:", error);
return false;
}
}
export const POST: APIRoute = async ({ request }) => { export const POST: APIRoute = async ({ request }) => {
try { try {
console.log("Received change password request"); console.log("Received change password request");
@ -81,6 +129,7 @@ export const POST: APIRoute = async ({ request }) => {
// Extract required parameters // Extract required parameters
const { const {
userId, userId,
currentPassword,
newPassword, newPassword,
logtoAppId, logtoAppId,
logtoAppSecret, logtoAppSecret,
@ -91,6 +140,7 @@ export const POST: APIRoute = async ({ request }) => {
// Validate required parameters // Validate required parameters
const missingParams = []; const missingParams = [];
if (!userId) missingParams.push("userId"); if (!userId) missingParams.push("userId");
if (!currentPassword) missingParams.push("currentPassword");
if (!newPassword) missingParams.push("newPassword"); if (!newPassword) missingParams.push("newPassword");
if (!logtoAppId) missingParams.push("logtoAppId"); if (!logtoAppId) missingParams.push("logtoAppId");
if (!logtoAppSecret) missingParams.push("logtoAppSecret"); if (!logtoAppSecret) missingParams.push("logtoAppSecret");
@ -130,6 +180,27 @@ export const POST: APIRoute = async ({ request }) => {
); );
} }
// Verify current password before proceeding
const isPasswordValid = await verifyUserPassword(
logtoApiEndpoint,
userId,
currentPassword,
accessToken,
);
if (!isPasswordValid) {
return new Response(
JSON.stringify({
success: false,
message: "Current password is incorrect",
}),
{
status: 400,
headers: { "Content-Type": "application/json" },
},
);
}
// Change password using Logto Management API // Change password using Logto Management API
const changePasswordResponse = await fetch( const changePasswordResponse = await fetch(
`${logtoApiEndpoint}/api/users/${userId}/password`, `${logtoApiEndpoint}/api/users/${userId}/password`,