91 lines
2.3 KiB
C++
91 lines
2.3 KiB
C++
#include "validation.h"
|
|
|
|
#include <cctype>
|
|
|
|
namespace radiantwave::validation {
|
|
|
|
bool isValidEmail(const std::string& email) {
|
|
if (email.size() < 3 || email.size() > 254) {
|
|
return false;
|
|
}
|
|
|
|
const size_t at = email.find('@');
|
|
if (at == std::string::npos || at == 0 || at == email.size() - 1) {
|
|
return false;
|
|
}
|
|
if (email.find('@', at + 1) != std::string::npos) {
|
|
return false;
|
|
}
|
|
|
|
for (unsigned char c : email) {
|
|
if (std::isspace(c)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
const std::string local = email.substr(0, at);
|
|
const std::string domain = email.substr(at + 1);
|
|
|
|
// Local part: alphanumerics plus ._%+- , but never leading/trailing dots.
|
|
if (local.front() == '.' || local.back() == '.') {
|
|
return false;
|
|
}
|
|
for (unsigned char c : local) {
|
|
if (!(std::isalnum(c) || c == '.' || c == '_' || c == '%' || c == '+' || c == '-')) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Domain part: dot-separated labels of alphanumerics/hyphens.
|
|
if (domain.front() == '.' || domain.back() == '.') {
|
|
return false;
|
|
}
|
|
int labels = 0;
|
|
size_t start = 0;
|
|
for (size_t i = 0; i <= domain.size(); ++i) {
|
|
if (i == domain.size() || domain[i] == '.') {
|
|
const size_t len = i - start;
|
|
if (len == 0) {
|
|
return false;
|
|
}
|
|
for (size_t j = start; j < i; ++j) {
|
|
const unsigned char c = static_cast<unsigned char>(domain[j]);
|
|
if (!(std::isalnum(c) || c == '-')) {
|
|
return false;
|
|
}
|
|
}
|
|
++labels;
|
|
start = i + 1;
|
|
}
|
|
}
|
|
return labels >= 2;
|
|
}
|
|
|
|
std::string sanitizeLicenseKey(const std::string& input) {
|
|
std::string out;
|
|
out.reserve(16);
|
|
for (unsigned char c : input) {
|
|
if (out.size() >= 16) {
|
|
break;
|
|
}
|
|
if (std::isalnum(c)) {
|
|
out += static_cast<char>(std::toupper(c));
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
std::string formatLicenseKey(const std::string& sanitized) {
|
|
std::string out;
|
|
out.reserve(19);
|
|
for (size_t i = 0; i < sanitized.size(); ++i) {
|
|
if (i > 0 && i % 4 == 0) {
|
|
out += '-';
|
|
}
|
|
out += sanitized[i];
|
|
}
|
|
return out;
|
|
}
|
|
|
|
} // namespace radiantwave::validation
|