void onTransactionRestored(const std::string &sku, const data::Value &data) { StoreProduct *product = getProduct(sku); if (product && data.isDictionary()) { product->validated = true; auto date = data.getInteger("purchaseTime"); product->purchased = true; product->available = true; product->confirmed = true; product->purchaseDate = Time::milliseconds(date); if (product->isSubscription) { product->expiration = Time::now() + TimeInterval::seconds(2 * 24 * 3600); } auto sk = StoreKit::getInstance(); StoreKit::onProductUpdate(sk, product->productId); StoreKit::onPurchaseCompleted(sk, product->productId); save(); #if (DEBUG) log::format("StoreKit", "Feature restored: %s", product->productId.c_str()); #endif } }
bool FieldExtra::transformValue(Scheme &scheme, data::Value &val) const { if (!val.isDictionary()) { return false; } auto &dict = val.asDict(); auto it = dict.begin(); while (it != dict.end()) { auto f_it = fields.find(it->first); if (f_it != fields.end()) { if (it->second.isNull()) { it ++; } else if (!f_it->second.transform(scheme, it->second)) { it = val.getDict().erase(it); } else { it ++; } } else { it = val.getDict().erase(it); } } if (!val.empty()) { return true; } return false; }
bool FieldPassword::transformValue(Scheme &scheme, data::Value &val) const { if (!val.isString()) { return false; } auto &str = val.getString(); if (str.size() < minLength || str.size() > maxLength) { return false; } val.setBytes(valid::makePassword(str, salt)); return true; }
void onFeatureInfo(const std::string &sku, const data::Value &data) { if (data.isDictionary()) { auto sk = StoreKit::getInstance(); StoreProduct *product = getProduct(sku); if (product) { product->price = data.getString("price"); product->available = true; product->validated = true; StoreKit::onProductUpdate(sk, product->productId); #if (DEBUG) log::format("StoreKit", "Feature: %s, Cost: %s", product->productId.c_str(), product->price.c_str()); #endif } } }
bool FieldArray::transformValue(Scheme &scheme, data::Value &val) const { if (val.isArray()) { if (tfield) { auto &arr = val.asArray(); auto it = arr.begin(); while (it != arr.end()) { if (!tfield.transform(scheme, *it)) { it = arr.erase(it); } else { ++ it; } } } return true; } return false; }
bool StoreProduct::updateWithData(const data::Value &val) { if (val.getString("productId") == productId && val.getBool("isSubscription") == isSubscription) { price = val.getString("price"); purchased = val.getBool("purchased"); duration = val.getInteger("duration"); expiration = Time::milliseconds(val.getInteger("expiration")); purchaseDate = Time::milliseconds(val.getInteger("purchaseDate")); available = val.getBool("available"); #if (ANDROID) token = val.getString("token"); signature = val.getString("signature"); #endif validated = false; return true; } return false; }
void Transform::performTransform(data::Value &value, Vector<data::Value *> &stack, const Pair<String, Transform> &it) const { stack.push_back(&value); auto & val = value.getValue(it.first); if (val.isDictionary()) { it.second.makeTransform(val, stack); } stack.pop_back(); }
void initHandlers(Server &serv, data::Value &val) { for (auto &it : val.asArray()) { if (it.isDictionary()) { auto & name = it.getString("name"); auto & file = it.getString("file"); auto & symbol = it.getString("symbol"); auto & handlerData = it.getValue("data"); onHandler(serv, name, file, symbol, handlerData); } } }
void Transform::performTransform(data::Value &value, Vector<data::Value *> &stack, const Pair<String, Vector<String>> &it) const { if (value.hasValue(it.first)) { if (it.second.empty()) { value.erase(it.first); } else if (it.second.size() == 1) { if (it.second.front().empty()) { value.erase(it.first); } else if (it.first != it.second.front()) { value.setValue(std::move(value.getValue(it.first)), it.second.front()); value.erase(it.first); } } else { if (it.first != it.second.front()) { data::Value *target = &value; size_t size = it.second.size(); size_t stackLevel = 0; size_t i = 0; while (i < size && it.second.at(i).empty()) { ++ stackLevel; ++ i; } if (stackLevel <= stack.size() && i < size) { if (stackLevel > 0) { target = stack.at(stack.size() - stackLevel); } auto &key = it.second.at(i); for (; i < size - 1; i++) { auto &val = target->getValue(key); if (val.isDictionary()) { target = &val; } else if (val.isNull()) { target = &target->setValue(Value(Value::Type::DICTIONARY), key); } else { break; } } if (i == size - 1) { target->setValue(std::move(value.getValue(it.first)), it.second.back()); value.erase(it.first); } } } } } }
void Server::onBroadcast(const data::Value &val) { if (val.getBool("system")) { Root::getInstance()->onBroadcast(val); return; } if (!val.isString("url") || !val.hasValue("data")) { return; } if (val.getBool("message")) { String url = String(config::getServerToolsPrefix()) + config::getServerToolsShell(); auto it = Server_resolvePath(_config->websockets, url); if (it != _config->websockets.end() && it->second) { it->second->receiveBroadcast(val); } } auto &url = val.getString("url"); auto it = Server_resolvePath(_config->websockets, url); if (it != _config->websockets.end() && it->second) { it->second->receiveBroadcast(val.getValue("data")); } }
bool FieldText::transformValue(Scheme &scheme, data::Value &val) const { switch (type) { case Type::Text: if (!val.isBasicType()) { return false; } if (!val.isString()) { val.setString(val.asString()); } if (val.isString()) { auto &str = val.getString(); if (str.size() < minLength || str.size() > maxLength) { return false; } } switch (transform) { case Transform::None: case Transform::Text: if (!valid::validateText(val.getString())) { return false; } break; case Transform::Identifier: case Transform::Alias: if (!valid::validateIdentifier(val.getString())) { return false; } break; case Transform::Url: if (!valid::validateUrl(val.getString())) { return false; } break; case Transform::Email: if (!valid::validateEmail(val.getString())) { return false; } break; case Transform::Number: if (!valid::validateNumber(val.getString())) { return false; } break; case Transform::Hexadecimial: if (!valid::validateHexadecimial(val.getString())) { return false; } break; case Transform::Base64: if (!valid::validateBase64(val.getString())) { return false; } break; default: break; } break; case Type::Bytes: if (val.isString()) { auto &str = val.getString(); if (str.size() > 4 && strncasecmp(str.data(), "hex:", 4) == 0) { auto len = (str.size() - 4) / 2; if (len < minLength || len > maxLength) { return false; } val.setBytes(base16::decode(CharReaderBase(str.data() + 4, str.size() - 4))); } else if (str.size() > 7 && strncasecmp(str.data(), "base64:", 7) == 0) { auto len = base64::decodeSize(str.size() - 7); if (len < minLength || len > maxLength) { return false; } val.setBytes(base64::decode(CharReaderBase(str.data() + 7, str.size() - 7))); } } else if (val.isBytes()) { auto &bytes = val.getBytes(); if (bytes.size() < minLength || bytes.size() > maxLength) { return false; } } break; default: return false; break; } return true; }
bool Field::Slot::transformValue(Scheme &scheme, data::Value &val) const { if (!val.isBasicType() && type != Type::Data) { return false; } switch (type) { case Type::Data: break; case Type::Integer: val.setInteger(val.asInteger()); break; case Type::Float: val.setDouble(val.asDouble()); break; case Type::Boolean: if (val.isString()) { auto &str = val.getString(); if (str == "1" || str == "on" || str == "true") { val.setBool(true); } else { val.setBool(false); } } else { val.setBool(val.asBool()); } break; case Type::Object: if (val.isBasicType()) { val.setInteger(val.asInteger()); } else { return false; } break; case Type::Set: if (!val.isArray()) { return false; } break; default: return false; break; } return true; }
int parseOptionString(data::Value &ret, const std::string &str, int argc, const char * argv[]) { if (str == "help") { ret.setBool(true, "help"); } return 1; }
int parseOptionSwitch(data::Value &ret, char c, const char *str) { if (c == 'h') { ret.setBool(true, "help"); } return 1; }
bool run(const data::Value &args, const data::Value &opts) { if (args.size() < 3) { std::cerr << "At least 2 argument is required!\n"; return false; } bool pretty = opts.getBool("pretty"); auto file = filesystem::currentDir(args.getString(2)); if (!filesystem::exists(file)) { std::cerr << "No such file: " << file << "\n"; return false; } auto name = filepath::name(file); auto path = filepath::root(file); auto &cmd = args.getString(1); if (cmd == "split") { auto data = data::readFile(file); if (data.isArray()) { size_t count = data.size(); size_t i = 0; for (auto &it : data.asArray()) { if (it.hasValue("meta")) { auto prefix = it.getValue("meta").getString("prefix"); std::cout << "-- " << prefix << " [" << i + 1 << "/" << count << "] ... "; std::cout.flush(); data::Value val; val.addValue(std::move(it)); auto savePath = filepath::merge(path, name + "." + prefix + ".json"); filesystem::remove(savePath); data::save(val, savePath, (pretty?data::EncodeFormat::Pretty:data::EncodeFormat::Json)); std::cout << "DONE (" << savePath << ")\n"; } i++; } } return true; } else if (cmd == "erase") { auto data = data::readFile(file); if (data.isArray()) { size_t count = data.size(); size_t i = 0; for (auto &it : data.asArray()) { if (it.hasValue("meta")) { auto prefix = it.getValue("meta").getString("prefix"); std::cout << "-- " << prefix << " [" << i + 1 << "/" << count << "] ... "; std::cout.flush(); if (prefix == "apps_application") { auto &objs = it.getValue("objects"); for (auto &it : objs.asArray()) { it.erase("androiddevices"); it.erase("iosdevices"); it.erase("androiddevices_debug"); it.erase("iosdevices_debug"); } } std::cout << "DONE\n"; } i++; } } auto savePath = filepath::merge(path, name + ".erased.json"); data::save(data, savePath, (pretty?data::EncodeFormat::Pretty:data::EncodeFormat::Json)); } return false; }
void initSession(data::Value &val) { sessionName = val.getString("name"); sessionKey = val.getString("key"); sessionMaxAge = val.getInteger("maxage"); isSessionSecure = val.getBool("secure"); }