update 39839999

This commit is contained in:
equippedcoding-master
2025-10-10 20:57:48 -05:00
parent 744d037a02
commit 61d50fa9b2
85 changed files with 10935 additions and 3717 deletions

View File

@@ -9,13 +9,13 @@
class Controller {
constructor(environment, member_config, json_config){
console.log(member_config);
// console.log(member_config);
this.config = { "member": member_config, "json": json_config, "environment": environment };
this.membership = member_config.membership;
this.testing = true;
this.config.key = "passthrough";
console.log(json_config);
// console.log(json_config);
// TODO_4: user should already have json_data & records

View File

@@ -220,6 +220,7 @@
console.log("Appfactory Studio: SDK has not been initialized!");
return;
}
console.log(1);
applicationManager.apicall("/v1/payments/initialize_direct_payments",{
method: 'POST',
headers: {
@@ -310,6 +311,7 @@
"payment_intent": payment_intent
});
console.log(2);
self.appManager.apicall("/v1/payments/save_handler",{
method: 'POST',
headers: {
@@ -458,15 +460,6 @@
},1000);
}
__runPaypal2(){
const self = this;
function RunCreatePaypalPayment(){
@@ -641,8 +634,6 @@
RunCreatePaypalPayment();
}
__payaplCheckOutHtmlElement(paypal_style,self){
let showpaypalbutton = "";
if(self.options.showPaypalButton){
@@ -1609,7 +1600,6 @@
return;
}
// nnnnn
$("#paypal_terms_and_conditions").on("click",function(e){
e.preventDefault();
window.open("https://www.paypal.com/us/legalhub/privacy-full");
@@ -2447,6 +2437,7 @@
console.log(props);
console.log(directPayment);
console.log(3);
directPayment.appManager.apicall("/v1/payments/stripe_create_customer",{
method: 'POST',
body: JSON.stringify(props)
@@ -2477,6 +2468,7 @@
// reference_num: props.reference_num
}
console.log(4);
directPayment.appManager.apicall("/v1/payments/stripe_create_subscription",{
method: 'POST',
body: JSON.stringify(data)
@@ -2755,140 +2747,11 @@
});
}
function _stripe_subscribe(self){
// helper method for displaying a status message.
const setMessage = (message) => {
const messageDiv = document.querySelector('#messages');
messageDiv.innerHTML += "<br>" + message;
}
// Fetch public key and initialize Stripe.
let stripe, cardElement;
let data = {};
fetchJsonp(self.service_request_url + "?" + new URLSearchParams({type:"config",data: JSON.stringify(data)}), {
method: "get"
})
.then((resp) => resp.json())
.then((resp) => {
stripe = Stripe(resp.publishableKey);
const elements = stripe.elements();
cardElement = elements.create('card');
cardElement.mount('#card-element');
}).catch((err) => {
console.log(err);
});
// fetch('/config')
// .then((resp) => resp.json())
// .then((resp) => {
// stripe = Stripe(resp.publishableKey);
// const elements = stripe.elements();
// cardElement = elements.create('card');
// cardElement.mount('#card-element');
// });
// Extract the client secret query string argument. This is
// required to confirm the payment intent from the front-end.
const subscriptionId = window.sessionStorage.getItem('subscriptionId');
const clientSecret = window.sessionStorage.getItem('clientSecret');
// This sample only supports a Subscription with payment
// upfront. If you offer a trial on your subscription, then
// instead of confirming the subscription's latest_invoice's
// payment_intent. You'll use stripe.confirmCardSetup to confirm
// the subscription's pending_setup_intent.
// See https://stripe.com/docs/billing/subscriptions/trials
// Payment info collection and confirmation
// When the submit button is pressed, attempt to confirm the payment intent
// with the information input into the card element form.
// - handle payment errors by displaying an alert. The customer can update
// the payment information and try again
// - Stripe Elements automatically handles next actions like 3DSecure that are required for SCA
// - Complete the subscription flow when the payment succeeds
const form = document.querySelector('#subscribe-form');
form.addEventListener('submit', async (e) => {
e.preventDefault();
const nameInput = document.getElementById('name');
// Create payment method and confirm payment intent.
stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: cardElement,
billing_details: {
name: nameInput.value,
},
}
}).then((result) => {
if(result.error) {
setMessage(`Payment failed: ${result.error.message}`);
} else {
// Redirect the customer to their account page
setMessage('Success! Redirecting to your account.');
window.location.href = '/account.html';
}
});
});
}
async function _stripe_single_charge_payment_intent(options,cbStart,cbSuccess,cbBackEndError,cbStripeError,self){
let data = {
// customer: options.customer,
// mail_handlers: options.mail_handlers
};
fetchJsonp(self.service_request_url + "?" + new URLSearchParams({type:"signle-create-payment-intent",data: JSON.stringify(data)}), {
method: "get"
})
.then((resp) => resp.json())
.then(async (resp) => {
let clientSecret = resp.clientSecret;
if (resp.error) {
console.log(resp);
console.log(cbBackEndError);
if(cbBackEndError!=undefined && cbBackEndError!=null) cbBackEndError(resp);
return;
}
if(options.name==undefined) options.name = "";
if(options.email==undefined) options.email = "";
cbStart(resp.paymentIntent, async function(){
// Confirm the card payment given the clientSecret
// from the payment intent that was just created on
// the server.
const {error: stripeError, paymentIntent} = await options.stripe.confirmCardPayment(
clientSecret,
{
payment_method: {
card: options.card,
billing_details: {
name: options.name,
phone: "713-777-5555",
_member_reference_num: options._member_reference_num
},
},
metadata: {
}
}
);
if (stripeError) {
console.log(stripeError);
if(cbStripeError!=undefined && cbStripeError!=null) cbStripeError(stripeError);
return;
}
cbSuccess(paymentIntent);
});
}).catch((err) => {
console.error(err);
// cb(null,null);
});
}
async function _stripe_standalone_payment(props,cb,self){
let data = {};
@@ -3718,6 +3581,21 @@
}
function EmailHandlerAddResponseEmail(email,mail_handlers){
if(email!=undefined && email!=null){
for(let prop1 in mail_handlers){
for(let prop2 in mail_handlers[prop1].handlers){
if(mail_handlers[prop1].handlers[prop2]['alert']==true)
continue;
mail_handlers[prop1].handlers[prop2]['emails'] = [email];
}
}
}
return mail_handlers;
}
// nnnnn
class Utils {
@@ -3736,6 +3614,16 @@
return rest + "." + lastTwo;
}
static numberId(len){
let text = "";
let possible = "0123456789";
if(len==null || len==undefined) len = 5;
for( var i=0; i < len; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
}
@@ -3757,6 +3645,55 @@
}
/**
*
* @example
* path: "/path",
data: {
code: code,
direct_payment: JSON.stringify(direct_payments_obj)
}
*
* @param {object} params
* @param {function} cb
* @param {boolean} raw - should the params be added together for a get request
* @returns
*/
function callAPI(params,cb,raw=true){
// const url = GetUrl('stripe');
// https://api.appfactory.studio/v1/modules/stripe/webhook
// let urlpath = "https://www." + applicationManager.config.api.json.url + "/portal/admin/core/api/php/request.php";
// let urlpath = "https://api.appfactory.studio/v1/modules/stripe" + params.path;
let urlpath = "https://api." + applicationManager.config.api.json.url + "" + params.path;
// let urlpath = "/portal/admin/core/api/php/includes/services/payments/stripe/stripe_payments.php"
let http = new XMLHttpRequest();
let urlEncodedData = "", urlEncodedDataPairs = [], name;
if(raw==false){
for( name in params ) {
urlEncodedDataPairs.push(encodeURIComponent(name)+'='+encodeURIComponent(params[name]));
}
}
const URL = urlpath;
http.open('POST', URL, true);
// http.setRequestHeader('Content-Type', 'application/json');
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
http.onreadystatechange = function() {
// if(http.readyState == 4 && http.status == 200) {
if ((http.readyState == 4) && (http.status >= 200 && http.status < 300)) {
// console.log(http);
cb(JSON.parse(http.responseText));
}
}
if(raw==false){
http.send(urlEncodedDataPairs.join("&"));
}else{
http.send(JSON.stringify(params));
}
}
function callStripe(params,cb,raw=true){
// const url = GetUrl('stripe');
// https://api.appfactory.studio/v1/modules/stripe/webhook
@@ -3843,7 +3780,7 @@
}
function stripeApplyDiscount(code,cb){
function stripeApplyDiscount(code, price_id, amount, cb){
let direct_payments_obj = sessionStorage.getItem('afs_direct_payment');
if(direct_payments_obj==undefined){
console.log("error - no direct payment");
@@ -3852,24 +3789,23 @@
let client_id = direct_payments_obj._processor.json.client_id;
// may not needed
let price = sessionStorage.getItem('mystripe_price');
if(price==undefined || price==null){
return;
}
if(price==undefined || price==null){ return; }
price = JSON.parse(price);
console.log(price);
console.log(direct_payments_obj);
// AQGTB0WN
callStripe({
path: "/apply_coupon",
apply_coupon: true,
code: code,
price_id: price.id,
direct_payment: JSON.stringify(direct_payments_obj)
data: {
code: code,
price_id: price_id, //price.id,
amount: amount,
direct_payment: JSON.stringify(direct_payments_obj)
}
},function(resp){
// resp = JSON.parse(resp);
// console.log(resp);
if(resp.message!=undefined){
cb(resp);
@@ -3878,9 +3814,6 @@
sessionStorage.setItem('mystripe_coupon_object',JSON.stringify(resp));
cb(resp);
});
}
// rrrrr
@@ -3896,8 +3829,6 @@
setupCb(stripeManager);
RegisterStripeEvents(stripeManager);
$(options.submit_id).on("click", async function(e){
e.preventDefault();
@@ -3910,9 +3841,10 @@
// elements,cardNumber,cardCvc,cardExpiry
let coupon = sessionStorage.getItem('mystripe_coupon_object');
console.log(coupon);
// console.log(coupon);
if(coupon!=undefined && coupon!=null){
coupon = JSON.parse(coupon);
// TODO_1: Stripe taxes is not applied to coupon
_stripeWithCoupon(coupon,cardNumber,elements,stripe,direct_payments_obj,action,errCb,successCb,stripeManager);
}else{
_stripeWithoutCoupon(elements,cardNumber,stripe,direct_payments_obj,action,errCb,successCb,stripeManager);
@@ -3928,22 +3860,21 @@
data.resultsCallback();
}
});
document.addEventListener("update:tax",function(e){
document.addEventListener("update:tax",function(e){
console.log(e.detail);
_stripeEventUpdateTax(stripeManager,e.detail);
});
}
function _stripeEventUpdateTax(stripeManager,data){
if(stripeManager._saved_postal_code.trim()==data.data.address.postal_code.trim()){
return;
}
console.log(data);
// if(stripeManager._saved_postal_code.trim()==data.data.address.postal_code.trim()){
// return;
// }
stripeManager._saved_postal_code = data.data.address.postal_code.trim();
// console.log(data);
const stripe = stripeManager.getStripe(); //Stripe(client_id);
stripeManager._card_elements = {};
const stripe = stripeManager.getStripe();
if(stripeManager._cardIsMounted==false){
const appearance = {
rules: {
'.Tab': {
@@ -3967,7 +3898,7 @@
// See all supported class names and selector syntax below
}
};
const stripeOptions = {
stripeManager._card_elements.stripeOptions = {
// hidePostalCode: true,
layout: {
type: 'accordion',
@@ -3980,7 +3911,7 @@
}
}
};
const elements = stripe.elements({
stripeManager._card_elements.elements = stripe.elements({
fonts: [
{
cssSrc: 'https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap'
@@ -3990,7 +3921,7 @@
// const elements = stripe.elements({appearance});
const cardNumber = elements.create('cardNumber', {
stripeManager._card_elements.cardNumber = stripeManager._card_elements.elements.create('cardNumber', {
// hidePostalCode: true,
style: {
base: {
@@ -4000,7 +3931,7 @@
}
});
const cardExpiry = elements.create('cardExpiry', {
stripeManager._card_elements.cardExpiry = stripeManager._card_elements.elements.create('cardExpiry', {
style: {
base: {
color: '#555',
@@ -4009,7 +3940,7 @@
}
});
const cardCvc = elements.create('cardCvc', {
stripeManager._card_elements.cardCvc = stripeManager._card_elements.elements.create('cardCvc', {
style: {
base: {
color: '#555',
@@ -4018,7 +3949,7 @@
}
});
const addressElement = elements.create("address", {
stripeManager._card_elements.addressElement = stripeManager._card_elements.elements.create("address", {
mode: "billing", // or "shipping"
defaultValues:{
name: "James Mitchell",// data.data.name,
@@ -4027,7 +3958,7 @@
});
const cardZip = elements.create('postalCode', {
stripeManager._card_elements.cardZip = stripeManager._card_elements.elements.create('postalCode', {
style: {
base: {
color: '#555',
@@ -4036,25 +3967,41 @@
}
});
stripeManager.getTax(data.data,function(results){
// console.log("mounting");
// console.log(data.data);
// console.log(results);
}
addressElement.mount("#address_no_mount");
cardNumber.mount(stripeManager.getOptions().card.cardNumber);
cardExpiry.mount(stripeManager.getOptions().card.cardExpiry);
cardCvc.mount(stripeManager.getOptions().card.cardCVC);
stripeManager.getTax(data.data, function(results){
console.log("mounting");
console.log(data.data);
console.log(results);
if(stripeManager._cardIsMounted==false){
// TODO_1: Stripe change to user supplied id
stripeManager._card_elements.addressElement.mount("#address_no_mount");
stripeManager._card_elements.cardNumber.mount(stripeManager.getOptions().card.cardNumber);
stripeManager._card_elements.cardExpiry.mount(stripeManager.getOptions().card.cardExpiry);
stripeManager._card_elements.cardCvc.mount(stripeManager.getOptions().card.cardCVC);
stripeManager._card_elements.cardNumber.on('ready', function() {
// console.log('Stripe card element is ready and mounted.');
// You can now safely interact with the element, e.g., card.focus();
stripeManager._cardIsMounted = true;
});
stripeManager.elements = {
elements:stripeManager._card_elements.elements,
cardNumber:stripeManager._card_elements.cardNumber,
cardCvc:stripeManager._card_elements.cardCvc,
cardExpiry:stripeManager._card_elements.cardExpiry,
addressElement:stripeManager._card_elements.addressElement
};
}
if(data.resultsCallback!=undefined){
data.resultsCallback(results);
data.resultsCallback(results, stripeManager._cardIsMounted);
}
stripeManager.elements = {
elements,cardNumber,cardCvc,cardExpiry,addressElement
};
});
}
@@ -4208,7 +4155,7 @@
});
} else {
console.log('Address not complete or valid:');
console.log('Address not complete or invalid:');
}
});
}
@@ -4222,8 +4169,8 @@
}
class StripeEvents {
#customEvent_display_card;
#customEvent_update_tax;
#customEvent_display_card = null;
#customEvent_update_tax = null;
constructor(){}
trigger(event,data = {}){
@@ -4236,7 +4183,7 @@
// document.dispatchEvent(this.#customEvent);
}else if(event=="update:tax"){
this.#customEvent_update_tax = new CustomEvent("update:tax",{
detail:data
detail: data
});
document.dispatchEvent(this.#customEvent_update_tax);
}
@@ -4258,6 +4205,7 @@
#tax_calculation_id;
_is_initialized = false;
_saved_postal_code = "";
_cardIsMounted = false;
#options;
constructor(direct_payment,options){
this.events = new StripeEvents();
@@ -4318,12 +4266,13 @@
customer_created: isCustomerCreated,
payment_intent_created: isPaymentIntentCreated,
payment_method_created: isPaymentMethodCreated,
amount: opts.amount,
customer_id: this.#customer_id,
payment_intent_id: this.#payment_intent_id,
payment_method_id: this.#payment_method_id,
product_id: this.#product_id,
amount: this.#options.amount,
// amount: this.#options.amount,
address: opts.address
}
callStripe({
@@ -4548,13 +4497,336 @@
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
//////// CatalogSubscribers
// nnnnn
class Subscriber {
constructor(email,name,phone){
this.email = email;
this.name = name;
this.phone = phone;
this.catalogs = [];
this.reference_num = "s"+ Utils.numberId(21);
}
setCatalogs(catalogs){
this.catalogs = catalogs;
}
buildSubscriber(){
let self = this;
let catalogs = [];
for (let i = 0; i < self.catalogs.length; i++) {
const catalog = self.catalogs[i];
catalogs.push({
"reference_num": catalog.reference_num,
"active": true
});
}
return {
email: self.email,
reference_num: self.reference_num,
json: {
phone: self.phone,
name: (self.name==undefined) ? "" : self.name,
catalogs: catalogs
},
date: moment().format('LLL')
};
}
addCatalog(catalog){
let self = this;
self.catalogs.push(catalog);
}
getCatalogs(){ return this.catalogs; }
}
class AFSSubscriber {
constructor() {
const self = this;
// self.app = app;
// self.managed_domain = managed_domain;
self.catalogs = [];
self.subscriber = {};
self._props_ = {
"has_been_updated": []
};
}
requestCatalogs(cb){
const self = this;
callAPI({
path: "/v1/modules/subscribers/get_catalogs",
},function(resp){
// console.log(resp);
if(resp.message!=undefined && resp.message=="request_failure"){
console.log("Error - no catalogs!");
return;
}
self.catalogs = resp.catalogs;
if(cb!=undefined) cb(resp.catalogs);
});
}
/**
*
* app.extra.config.configurations.subscriber
*
* @returns array
*/
getCatalogs() {
return this.catalogs;
}
/**
* Get catalog by reference_num or the index within the subscribers array.
* can return null.
*
* @param {string|number} index - The index or reference_num
* @returns object | null app.extra.config.configurations.subscriber[catalog].json
*/
getCatalog(index) {
const self = this;
let saveindex = -1;
if(typeof index === 'number'){
if(self._exist_catalog(index)){
return self.getCatalogs()[index];
}else{
return null;
}
}
if(typeof index === 'string'){
for (let i = 0; i < self.getCatalogs().length; i++) {
if(self.getCatalogs().reference_num==index){
saveindex = i;
break;
}
}
}
if(saveindex==-1){
return null;
}else{
return self.getCatalogs()[saveindex].json;
}
}
initializeSubscriber(email,name,phone){
return new Subscriber(email,name,phone);
}
addCatalogSubscriber(catalog,subscriber){
subscriber.addCatalog(catalog);
}
createSubscriber(sub,mail_handlers,cb,sendresponse){
let self = this;
if(sub.getCatalogs().length==0) return;
if(sendresponse==undefined) sendresponse = true;
let subBuild = sub.buildSubscriber();
console.log(subBuild);
const response_email = subBuild['email'];
// nnnnn
mail_handlers = EmailHandlerAddResponseEmail(response_email,mail_handlers);
// console.log(mail_handlers);
callAPI({
path: "/v1/modules/subscribers/create_subscriber",
data: {
token: "token",
subscriber: subBuild,
mail_handlers: mail_handlers,
sendresponse: sendresponse
}
},function(resp){
console.log(resp);
if(cb!=undefined) cb();
});
// let email_response = structuredClone(self.app.extra.config.configurations.subscriber[1].json.mail_handlers.email_response);
// const settings = self.app.extra.config.configurations.settings[0].json;
// let sysVars = self.app.extra.extras.SetupSystemVariables(self.app);
// let sysVars = [];
// sysVars.push({
// name: "email",
// value: sub.email
// });
// sysVars.push({
// name: "manage_subscription_link",
// value: self.app.extra.config.managed_domain.Address + `/portal/pages/subscriber/manage.php?email=${sub.email}&reference_num=${sub.reference_num}`
// });
// email_response.emails = [sub.email];
// email_response.variables.client = [structuredClone(email_response.variables.client)];
// email_response.variables.schema = [structuredClone(email_response.variables.schema)];
// email_response.variables.system = [structuredClone(self.app.extra.extras.SetupSystemVariables(self.app, email_response))];
// let subBuild = sub.buildSubscriber();
// console.log(subBuild);
// $.post(self.app.extra.url,{
// client_subscriber_add_subscriber: true,
// token: self.app.extra.token,
// subscriber: JSON.stringify(subBuild),
// response: JSON.stringify(email_response),
// sendresponse: sendresponse,
// },function(resp1){
// resp1 = JSON.parse(resp1);
// if(cb!=undefined) cb(resp1);
// });
}
/**
* Check if catalog exist in array given index.
*
* @param {number} index
* @returns
*/
_exist_catalog(index){
const self = this;
if(typeof self.catalogs[index] === 'undefined') {
return false;
}
else {
return true;
}
}
updateSubscriberConfiguration(provider,cb1){
const self = this;
let updates = self._props_.has_been_updated;
let catalogs = [];
for (let i = 0; i < updates.length; i++) {
const element = updates[i];
const catalog = self.getCatalog(element.catalog_reference_num);
if(catalog==null){
console.log(`Catalog ${element.catalog_reference_num} does not exist`);
continue;
}
catalogs.push(catalog);
}
let email_response = structuredClone(self.app.extra.config.configurations.subscriber[1].json.mail_handlers.email_response);
// const settings = self.app.extra.config.configurations.settings[0].json;
// let sysVars = self.app.extra.extras.SetupSystemVariables(self.app);
let sysVars = [];
sysVars.push({
name: "email",
value: provider.email
});
sysVars.push({
name: "subscription_manage_button_link",
value: self.app.extra.config.managed_domain.Address + `/portal/pages/subscriber/manage.php?email=${provider.email}&reference_num=${provider.reference_num}`
});
email_response.emails = [provider.email];
email_response.variables.client = [structuredClone(email_response.variables.client)];
email_response.variables.schema = [structuredClone(email_response.variables.schema)];
email_response.variables.system = [structuredClone(email_response.variables.system)];
// console.log(sysVars);
// console.log(provider);
// console.log(catalogs);
// if(catalogs.length==0) return;
// $.post(self.app.extra.url,{
// add_subscriber: true,
// catalogs: JSON.stringify(catalogs),
// response: JSON.stringify(email_response)
// },function(resp1){
// self.clear();
// if(cb1!=undefined) cb1(catalogs,resp1);
// });
}
deleteAllSubscribers(){
for (let i = 0; i < app.extra.config.configurations.subscriber.length; i++) {
app.extra.config.configurations.subscriber[i] = [];
let senddata ={
configurations_update:true,
mysql_id: app.extra.config.configurations.subscriber[i].json.mysql_id,
data: JSON.stringify(app.extra.config.configurations.subscriber[i].json)
}
$.post(app.extra.url,senddata,function(resp){
console.log(resp)
});
}
}
sendConfirmationEmail(email,cb){
// const self = this;
// const list = [];
// const updates = self._props_.has_been_updated;
// for (let i = 0; i < updates.length; i++) {
// const catalog = self.getCatalog(updates[i].catalog_reference_num);
// if(catalog==null) continue;
// list.push(catalog.display_name);
// }
// const data = {
// subscriber_confirm_subscribed: true,
// catalog_display_names: JSON.stringify(list),
// email: email
// };
// $.post(self.app.url,data,function(resp){
// if(cb!=undefined) cb(resp);
// });
}
clear(){
this._props_.has_been_updated = [];
}
addCatalogSubscriber2(catalog,subscriber){
const self = this;
const cfn = catalog.reference_num;
if(self.getCatalog(cfn)!=null){
if(self.getCatalog(cfn)!=null){
_addorupdateCatalogSubscriber(subscriber, cfn, self);
}else{
console.log(`[]: catalog ${cfn} not found`);
}
}else{
console.log(`[]: catalog ${cfn} not found`);
}
}
}
return {
InitializeClientSDK: InitializeClientSDK,
DirectPayments: DirectPayments,
EmailHandler: EmailHandler,
PaymentsProcessor: PaymentsProcessor,
Utils: Utils,
AFSSubscriber:AFSSubscriber,
GetMyUrl,

View File

@@ -28,7 +28,6 @@ $router->post('/get_tax',[AppfactoryStudio\Plugins\StripeModule::class, 'get_tax
// Setup
$router->get('/setup_stripe_register_plans',[AppfactoryStudio\Plugins\StripeModule::class, 'RegisterSubscriptionPlans']);

View File

@@ -0,0 +1,113 @@
########## BEGIN RECOMMENDED RULES (COMMENT OUT OR UNCOMMENT AS NEEDED) ##########
### htaccess (https://github.com/delight-im/htaccess)
### Copyright (c) delight.im (https://www.delight.im/)
### Licensed under the MIT License (https://opensource.org/licenses/MIT)
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization"
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
<IfModule mod_autoindex.c>
# Turn off directory listings for folders without default documents
Options -Indexes
</IfModule>
<IfModule mod_negotiation.c>
# Disable 'MultiViews' implicit filename pattern matches
Options -MultiViews
</IfModule>
# Serve "text/plain" and "text/html" documents as UTF-8 by default
AddDefaultCharset utf-8
# Disable "ETag" headers so that browsers rely on the "Cache-Control" and "Expires" headers
FileETag None
<ifModule mod_headers.c>
# Enable HTTP Strict Transport Security (HSTS) with a duration of six months (Uncomment 1 line below)
# Header set Strict-Transport-Security max-age=15778800
</ifModule>
<ifModule mod_rewrite.c>
# Force 'www' (i.e. prefix the "bare" domain and all subdomains with 'www' through permanent redirects) (Uncomment 6 lines below)
# RewriteCond %{HTTP_HOST} !^$
# RewriteCond %{HTTP_HOST} !^www\. [NC]
# RewriteCond %{HTTPS}s ^on(s)|
# # RewriteCond %{REQUEST_SCHEME} ^http(s)|
# # RewriteCond %{SERVER_PORT}s ^443(s)|
# RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Force HTTPS (Uncomment 4 lines below)
# RewriteCond %{HTTPS} off
# # RewriteCond %{REQUEST_SCHEME} http
# # RewriteCond %{SERVER_PORT} !443
# RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
# Prevent access to non-minified CSS and JS (Uncomment 3 lines below)
# <FilesMatch "(?<!.min)\.(css|js)$">
# Require all denied
# </FilesMatch>
# Show a custom error document for "404 Not Found" errors (Uncomment 1 line below)
# ErrorDocument 404 /notFound.html
# Announce contact information for security issues (Uncomment 2 lines below)
# Header set X-Vulnerability-Disclosure "https://www.example.com/security"
# Header set X-Security-Contact "security@example.com"
########## END RECOMMENDED RULES ##########
########## BEGIN CUSTOM RULES (YOUR OWN RULES GO HERE) ##########
# Add your rules here ...
########## END CUSTOM RULES ##########
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /v1/modules/subscribers/index.php [L]
</IfModule>
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
# Prevent clickjacking (forbids framing by third-party sites)
Header set X-Frame-Options sameorigin
# Prevent content sniffing (MIME sniffing)
Header set X-Content-Type-Options nosniff
# Attempt to enable XSS filters in browsers, if available, and block reflected XSS
Header set X-XSS-Protection "1; mode=block"
# Cache media files for a month
<FilesMatch "\.(js|css|jpg|jpeg|png|svg|webp|gif|ico|ogg|mp4|webm)$">
Header set Cache-Control max-age=2629800
</FilesMatch>
# Remove response headers that provide no value but leak information
Header always unset X-Powered-By
Header unset Server
# Disable "ETag" headers so that browsers rely on the "Cache-Control" and "Expires" headers
Header unset ETag
</IfModule>

View File

@@ -0,0 +1,21 @@
<?php
// require __DIR__ . "/vendor/autoload.php";
$dir = dirname( __DIR__, 4 );
$path = $dir . "/admin/core/api/php/includes/init.php";
require $path;
$router = new AppfactoryStudio\Core\Router();
// TODO_1: Rate limit or even ban ips that are not stripe to prevent DDOS attacks
$router->post('/get_catalogs',[AppfactoryStudio\Plugins\Subscribers::class, 'get_catalogs']);
$router->get('/get_catalogs',[AppfactoryStudio\Plugins\Subscribers::class, 'get_catalogs']);
$router->post('/create_subscriber',[AppfactoryStudio\Plugins\Subscribers::class, 'create_subscriber']);
echo $router->UrlResolve("/v1/modules/subscribers", $_SERVER['REQUEST_URI'], strtolower($_SERVER['REQUEST_METHOD']));