/** * Complete user profile after phone verification * * POST: { * "firstName": "John", * "lastName": "Smith", * "email": "john@example.com" * } * * Requires auth token in header: X-User-Token: * (Parsed by Application.cfm into request.UserID) * * Returns: { OK: true } and sends confirmation email */ function apiAbort(required struct payload) { writeOutput(serializeJSON(payload)); abort; } function readJsonBody() { var raw = getHttpRequestData().content; if (isNull(raw)) raw = ""; if (!len(trim(raw))) return {}; try { var data = deserializeJSON(raw); if (isStruct(data)) return data; } catch (any e) {} return {}; } function getAuthUserId() { // Use request.UserID set by Application.cfm from X-User-Token header if (structKeyExists(request, "UserID") && isNumeric(request.UserID) && request.UserID > 0) { return request.UserID; } return 0; } function isValidEmail(required string email) { return reFind("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", arguments.email) > 0; } try { userId = getAuthUserId(); if (userId == 0) { apiAbort({ "OK": false, "ERROR": "unauthorized", "MESSAGE": "Authentication required" }); } data = readJsonBody(); firstName = structKeyExists(data, "firstName") ? trim(data.firstName) : ""; lastName = structKeyExists(data, "lastName") ? trim(data.lastName) : ""; email = structKeyExists(data, "email") ? trim(lCase(data.email)) : ""; // Validate required fields if (!len(firstName)) { apiAbort({ "OK": false, "ERROR": "missing_first_name", "MESSAGE": "First name is required" }); } if (!len(lastName)) { apiAbort({ "OK": false, "ERROR": "missing_last_name", "MESSAGE": "Last name is required" }); } if (!len(email) || !isValidEmail(email)) { apiAbort({ "OK": false, "ERROR": "invalid_email", "MESSAGE": "Please enter a valid email address" }); } // Check if email is already used by another verified account qEmailCheck = queryExecute(" SELECT UserID FROM Users WHERE UserEmailAddress = :email AND UserIsEmailVerified = 1 AND UserID != :userId LIMIT 1 ", { email: { value: email, cfsqltype: "cf_sql_varchar" }, userId: { value: userId, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); if (qEmailCheck.recordCount > 0) { apiAbort({ "OK": false, "ERROR": "email_exists", "MESSAGE": "This email is already associated with another account" }); } // Get current user UUID for email confirmation link qUser = queryExecute(" SELECT UserUUID FROM Users WHERE UserID = :userId ", { userId: { value: userId, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); // Update user profile AND mark account as verified/active // This completes the signup process queryExecute(" UPDATE Users SET UserFirstName = :firstName, UserLastName = :lastName, UserEmailAddress = :email, UserIsEmailVerified = 0, UserIsContactVerified = 1, UserIsActive = 1 WHERE UserID = :userId ", { firstName: { value: firstName, cfsqltype: "cf_sql_varchar" }, lastName: { value: lastName, cfsqltype: "cf_sql_varchar" }, email: { value: email, cfsqltype: "cf_sql_varchar" }, userId: { value: userId, cfsqltype: "cf_sql_integer" } }, { datasource: "payfrit" }); // Send confirmation email confirmLink = "https://biz.payfrit.com/confirm_email.cfm?UUID=" & qUser.UserUUID; emailBody = "

Welcome to Payfrit, #firstName#!

Please click the link below to confirm your email address:

Confirm Email

Or copy and paste this URL into your browser:

#confirmLink#

Thanks,
The Payfrit Team

";
#emailBody# writeOutput(serializeJSON({ "OK": true, "MESSAGE": "Profile updated. Please check your email to confirm your address." })); } catch (any e) { apiAbort({ "OK": false, "ERROR": "server_error", "MESSAGE": e.message }); }