PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label backend. Show all posts
Showing posts with label backend. Show all posts

Tuesday, November 8, 2022

[FIXED] Why is it safe to store API keys in DigitalOceans API "Environment Variable" option when using "App Platform"?

 November 08, 2022     backend, digital-ocean, javascript, node.js, security     No comments   

Issue

I am setting up a NodeJS backend that needs to hold a few API keys to contact among others Firebase to authenticate users.

I have been able to publish the backend and succesfully get a HTTP reply from an API endpoint on it. I use Express to run the NodeJS API.

Now I wish the NodeJS API to act as my user and database contactpoint. But I am unsure where to safely store the API keys for the project. As I am relatively new to this type of security.

So, I have Googled around and found that people say that .env files are NOT safe places to store API Keys. Yet on the DigitalOcean documentation it says the following:

Environment variables are excellent places to store sensitive information (such as API keys), or information that needs to be globally accessible from anywhere in the app, (such as version numbers or hardcoded paths).

So my question is, what is the reason that DigitalOcean would say it is safe to store an API key in the environment variables when so many other sources say that it is not. Is this because the danger lies in the accessibility of the file and that DigitalOcean then somehow secures the file? I have noticed they have a "secret" boolean box you can tick, that says it will make it not appear in consoles. But will it also be completely inaccessible for people in general?

My main concern is to prevent hackers or people with bad intentions from accessing the API key. I am not concerned that people with legitimate access will abuse it, only people that dont have legitimate access.

Looking forward to your insights.


Solution

I will rank the security of storing secrets in the following orders (from less secure to the most):

  1. Storing them directly in your code (really, really bad)
  2. Store them in environment variables
  3. Storing them in files on disks
    • Access permission can be set, e.g., who can read it
    • If you load the content into env vars, it will be no different from Point 2
  4. Storing them in object stores (AWS S3, Google Cloud Storage)
  5. Storing them using secrets managers (AWS, GCP Secret Manager)
  6. Using IAM (not really a place to store secrete but a way to control who can access the secrets using the methods above).

Eloboration:

Point 2 & 3:

The difference between points 2 and 3 becomes obscure if your system is compromised. In this case, if the attacker has the root access, he/she can read/write/delete/change everything, so point 3 will fail. For point 2, the attacker can access environment variables via 3 methods:

According to @phmmmer in this post

  1. The running environment of the process When the process is running, the environment variables of that process can be > > accessed through /proc/$PID/environ. However, only the user who owns the process, or root, can access that file.

  2. The source of the environment variables If you're using an init script, and the variables are stored in that init script, the variables can, of course, be obtained by reading that script.

Or if the environment variables are coming from somewhere else, then wherever that is.

  1. 'ps' output Yeah, I know I said 2, and in any decent system, it will be 2. However, if the admin doesn't know what he's doing, it's possible to open up the 3rd avenue.

If the process is launched via something like sh -c 'cd /foo/bar; POP=tart /my/executable', then that sh process will be visible in ps:


$ ps ax | grep POP phemmer   3085  14   5  0.0  0.0 SN         00:00
sh -c cd /; POP=tart sleep 10```

Point 4:

You can store secrets as objects in object stores and download them during deployment or during boot time. Most of the object stores offer logging functionalities, so you can also monitor how your secrets are being used and who is using them. Note:Point 4 is good, if and only if you properly configure IAM permissions. Otherwise, it will be no different from Point 2, albeit now you are getting the file from a remote location.

Point 5:

Your application can call the secret managers' APIs in order to consume the secrets. Your secrets are not stored anywhere locally except in the memory. And, Yes. You can encrypt your memory as well, and you can read more in this post

Point 6:

IAMs or identity and access management are used to grant the right access to the right resource to the right person/user/application at the right time. It is not a storage for secrets, but it can be used to manage access to secret storage.

So, to answer your question:

"Environment variables are excellent places to store sensitive information" might be an overstatement from DO. But they do offer something more than just storing your sensitive information in environment variables and just leaving them there.

In the next post "How to Use Environment Variables in App Platform" of the documentation that you mentioned in your question, DO does offer some levels of access control and encryption regarding environment variables:

  1. Runtime variables
    • During app creation
    • Afer app creation
  2. Build time variables
  3. Bindable Variables within Environment Variables
    • App-wide variables
    • Component-specific variables

So when people are saying it is not safe to store sensitive information using environment variables, most of them are talking about vanilla env vars with no access control and encryption. And in this case, it is definitely not safe to store your API Keys there. Plain, vanilla environment variables should be used to store information like port numbers, production environments, or other non-sensitive information.

Here are some posts that I used as references for this answer:

  1. 5 ways to manage serverless secrets, ranked best to worst
  2. A comprehensive guide to managing secrets in your Terraform code
  3. DigitalOcean: How to Use Environment Variables in App Platform


Answered By - Aviv Lo
Answer Checked By - Gilberto Lyons (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, October 21, 2022

[FIXED] How can I store or obtain the inaccurate route that was searched for?

 October 21, 2022     backend, express, node.js     No comments   

Issue

In this case, how could I save the /india route in a variable in the router? app.get(‘*’, function(req, res){ //Save rute here; }


Solution

If you just want to log the bad route to a file, you can do something like this. Just make this is the last route you define so that all other routes get a chance to match before it does:

app.get("*", (req, res) => {
    // log the unhandled route
    fs.appendFile("bad-routes.txt", req.path + "\n", (err) => {
        if (err) {
            console.log(`Error attempting to append ${req.path} to bad-routes.txt`);
        }
    });
    res.sendStatus(404);
});

Note, in this list, you will probably find things that crawlers (not users) are also probing your site for.

The above logs only GET requests. If you want to log for all http verbs, you could do this:

app.use((req, res) => {
    // log the unhandled route
    fs.appendFile("bad-routes.txt", `${req.method}: ${req.path}\n`, (err) => {
        if (err) {
            console.log(`Error attempting to append ${req.path} to bad-routes.txt`);
        }
    });
    res.sendStatus(404);
});

It's possible that fs.appendFile() could have some race conditions if multiple requests were both trying to log. In that case, it would be safer to use a shared stream which will safely sequence the writes:

let logUnhandledStream;

app.use((req, res) => {
    // log the unhandled route
    if (!logUnhandledStream) {
        logUnhandledStream = fs.createWriteStream("bad-routes.txt", { flags: "a" });
        logUnhandledStream.on('error', err => {
            console.log(`Error attempting to log to bad-routes.txt`, err);
        });
    }
    logUnhandledStream.write(`${req.method}: ${req.path}\n`);
    res.sendStatus(404);
});


Answered By - jfriend00
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, September 26, 2022

[FIXED] How to allow clients to hook into preconfigured hooks in application

 September 26, 2022     backend, continuous-deployment, events, version-control, webhooks     No comments   

Issue

I have a pretty standard application with a frontend, a backend and some options in the frontend for modifying data. My backend fires events when data is modified (eg. record created, record updated, user logged in, etc.).

Now what I want to do is for my customers to be able to code their own functions and "hook" them into these events.

So far the approaches I have thought of are:

  1. Allowing users in the frontend to write some code in a codeeditor like codemirror, but this whole storing code and executing it with some eval() seems kind of risky and unstable.
  2. My second approach is illustrated below (to the best of my ability at least). The point is that the CRUD API calls a different "hook" web service that has these (recordUpdated, recordCreated, userLoggedIn,...) hook methods exposed. Then the client library needs to extend some predefined interfaces for the different hooks I expose. This still seems doable, but my issue is I can't figure out how my customers would deploy their library into the running "hook" service.

So it's kind of like webhooks, except I already know the exact hooks to be created which I figured could allow for an easier setup than customers having to create their own web services from scratch, but instead just create a library that is then deployed into an existing API (or something like that...). Preferably the infrastructure details should be hidden from the customers so they can focus solely on making business logic inside their custom hooks.

It's kind of hard to explain, but hopefully someone will get and can tell me if I'm on the right track or if there is a more standard way of doing hooks like these?

Currently the entire backend is written in C# but that is not a requirement.

enter image description here


Solution

I'll just draft out the main framework, then wait for your feedback to fill in anything unclear.

Disclaimer: I don't really have expertise with security and sandboxing. I just know it's an important thing, but really, it's beyond me. You go figure it out 😂

Suppose we're now in a safe sandbox where all malicious behaviors are magically taken care, let's write some Node.js code for that "hook engine".

How users deploy their plugin code.

Let's assume we use file-base deployment. The interface you need to implement is a PluginRegistry.

class PluginRegistry {
  constructor() {
    /**
    The plugin registry holds records of plugin info:

    type IPluginInfo = {
      userId: string,
      hash: string,
      filePath: string,
      module: null | object,
    }
    */

    this.records = new Map()
  }

  register(userId, info) {
    this.records.set(userId, info)
  }

  query(userId) {
    return this.records.get(userId)
  }
}

// plugin registry should be a singleton in your app.
const pluginRegistrySingleton = new PluginRegistry()

// app opens a http endpoint
// that accepts plugin registration
// this is how you receive user provided code
server.listen(port, (req, res) => {
  if (isPluginRegistration(req)) {
    let { userId, fileBytes, hash } = processRequest(req)
    let filePath = pluginDir + '/' + hash + '.js'

    let pluginInfo = {
      userId,
      // you should use some kind of hash
      // to uniquely identify plugin
      hash,
      filePath,
      // "module" field is left empty
      // it will be lazy-loaded when
      // plugin code is actually needed
      module: null,
    }

    let existingPluginInfo = pluginRegistrySingleton.query(userId)
    if (existingPluginInfo.hash === hash) {
      // already exist, skip
      res.writeHead(200, { 'Content-Type': 'text/plain' });
      res.end('ok');
    } else {
      // plugin code written down somewhere
      fs.writeFile(filePath, fileBytes, (err) => {
        pluginRegistrySingleton.register(userId, pluginInfo)
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('ok');
      })
    }

  }
})

From the perspective of hook engine, it simply opens a HTTP endpoint to accept plugin registration, agnostic to the source.

Whether it's from CI/CD pipeline, or plain web interface upload, it doesn't matter. If you have CI/CD setup for your user, it is just a dedicated build machine that runs bash scripts isn't it? So just fire a curl call to this endpoint to upload whatever you need. Same applies to web interface.

How we would execute plugin code

User plugin code is just normal Node.js module code. You might instruct them to expose certain API and conform to your protocol.

class HookEngine {
  constructor(pluginRegistry) {
    // dependency injection
    this.pluginRegistry = pluginRegistry
  }

  // hook
  oncreate(payload) {
    // hook call payload should identify the user
    const pluginInfo = this.pluginRegistry.query(payload.user.id)

    // lazy-load the plugin module when needed
    if (pluginInfo && !pluginInfo.module) {
      pluginInfo.module = require(pluginInfo.filePath)
    }

    // user plugin module is just normal Node.js module
    // you load it with `require`, and you call what ever function you need.
    pluginInfo.module.oncreate(payload)
  }
}


Answered By - hackape
Answer Checked By - Clifford M. (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, September 25, 2022

[FIXED] What is the purpose of signing a smart contract from the backend API? Is it secure?

 September 25, 2022     backend, blockchain, smartcontracts     No comments   

Issue

Since the transaction needs to be signed, it requires a private key, so how can the users interact with the backend API and send the private key securely.

I wonder what is the purpose of signing a smart contract from the backend API? Is there any solid real-world use case where a number of users need to interact through the backend to smart contract instead of frontend metamask to smart contract?


Solution

Mostly automated actions from your own wallet, so that you don't have to sign the transactions manually.

  • Trading bot sending automated buy and sell orders to a DEX contract from your own wallet based on some off-chain analysis. The script can run 24/7 not having to prompt you to sign the transaction each time.
  • Oracle pattern. Your own wallet is an authorized address on your sports bets contract, feeding it off-chain data who won a match. This way you can automate the process and not have to sign the transaction manually after each match.

As always in IT security, a chain is as strong as its weakest link. There are ways to securely store and use private keys. For example use a secrets management system, exclude sensitive values from logs, set up and review access to sensitive data (only certain users or apps are able to access it), ... Specifics depend on your implementation and how much value is at stake.



Answered By - Petr Hejda
Answer Checked By - Candace Johnson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, September 2, 2022

[FIXED] How to protect backend from being accessed by other unauthorised apps

 September 02, 2022     authentication, backend, frontend, security     No comments   

Issue

How to protect my backend from being accessed by other unauthorised front-end apps? I googled and couldn't find a solution that gives complete solution. How companies like Instagram,Facebook block unauthorised requests ? I read SSL keys can be found by reverse-engineering the front-end. I am a noob and building a social network for a project.Please guide me.


Solution

I'll try to get you started in the right direction.

How to protect my backend from being accessed by other unauthorised front-end apps?

You can protect your server by issuing access tokens. The only way a user can get a valid token is by authenticating with a valid username and password.

Typically, tokens are set to expire after a period of time. If you are looking for a turn key solution, JSON web tokens are a good place to start. More info here: https://jwt.io/

I googled and couldn't find a solution that gives complete solution. How companies like Instagram,Facebook block unauthorised requests ?

Facebook uses access tokens. https://developers.facebook.com/docs/facebook-login/access-tokens/

I read SSL keys can be found by reverse-engineering the front-end.

Access tokens can't be reverse engineered because they are not 'hard-coded' into the front-end. The access tokens are retrieved from the back-end via authentication. Additionally, tokens typically expire after a period of time. If the token has expired, then the user must re authenticate to receive a new (valid) token.



Answered By - bsheps
Answer Checked By - Terry (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, September 1, 2022

[FIXED] How do I get an API access token dynamically for an NGINX proxy

 September 01, 2022     api, backend, nginx, nginx-reverse-proxy, twitch-api     No comments   

Issue

I started to play around with the IGDB API for an iOS App. Some days ago IGDB launched V4 which now requires authorizing with Twitch via oAuth2 in order to receive an app access token.

With my poor backend knowledge (I literally started yesterday to learn about NGINX) I managed to set up an NGINX Webserver which proxies requests to the IGDB API and injects the app access token into the HTTP Header. This is working fine for now.

My proxy.conf which is included in the nginx.conf looks like this:

server {
    listen 443 ssl;
    server_name myhost.com;

    #SSL Config cut out  
    ...

    location / {
        proxy_pass https://api.igdb.com/v4/games;
        proxy_ssl_server_name on;
        proxy_set_header Client-ID "MY TWITCH APP CLIENT ID";
        proxy_set_header Authorization "Bearer THE_APP_ACCESS_TOKEN";
    }
}

However THE_APP_ACCESS_TOKEN was requested manually by me. For testing purposes this is fine, however it will expire after about 60 days (according to the Twitch Dev Docs). I am wondering now how I would dynamically request an access token (and store it somehow?), refresh it when it expires and inject it into the proxy.conf.

While researching I stumbled upon the HTTP Auth Request module in combination with the NGINX JavaScript module (https://www.nginx.com/blog/validating-oauth-2-0-access-tokens-nginx/).

Now I wonder if it is a reasonable approach to trigger a token request via the Auth Request Module before proxying the request, parse the JSON response with the JavaScript Module and inject the app access token contained in the response as a variable into the HTTP header of the proxy. While this sounds good to me in theory I barely have an idea how to implement this. Moreover, this approach does not yet include storing and updating the token as soon as it expires.

Do you have some hints for me how to tackle this or is there even another solution?


Solution

Okay, here's what I came up with. This seems to fit my use case:

  1. I wrote a shell script which makes a curl POST request to the twitch oAuth endpoint for getting an app access token and outputs the JSON response to a file (here: access.json)

    curl -o access.json -X POST 'https://id.twitch.tv/oauth2/token?client_id=<YOUR_CLIENT_ID>&client_secret=<YOUR_CLIENT_SECRET>&grant_type=client_credentials'

  2. After that, the script parses the value of the access_token key in the access.json with the jq command line tool and saves it to the variable newAccessToken. This is done with this line:

    newAccessToken=$(cat /<PATH_TO_JSON>/access.json | jq -r '.access_token')

    The cat command outputs the access.json and pipes it to the jq command which filters the json for the access_token key value.

  3. In the same directory of the script I placed a proxy_template.conf which consists all config information above but instead of the manually received access token it has the string "THEACCESSTOKEN".

  4. After storing the access_token key in the newAccessToken variable I search for the "THEACCESSTOKEN" string in the proxy_template.conf, replace it with the value of the newAccessToken variable and save the output in a new proxy.conf in the /etc/nginx/conf.d directory. This is done with the sed command:

    sed "s/THEACCESSTOKEN/$newAccessToken/g" /<PATH_TO_FILE>/proxy_template.conf > /nginx/etc/conf.d/proxy.conf

  5. In last line of the script I just nginx -s reload the server in order to use the new config file.

  6. In order to receive a fresh access token regularly I've set up a cron job which executes the shell script every day.

Not sure if this is the most elegant solution but it seems fine for my use case and works. If you have any other best practices I appreciate every hint. :)



Answered By - Svenson
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, August 4, 2022

[FIXED] how to add attributes to custom rails exceptions

 August 04, 2022     backend, error-handling, exception, ruby, ruby-on-rails     No comments   

Issue

Say I have a custom error class that inherits from a parent error class. How can I add an attribute to that class, so something like:

class CustomError <CustomParentErrorClass
  status: 500
end 

So that in my controller I could do something like

rescue CustomErroClass => e
 head(e.status)

I essentially want to access my attribute from my rails error class from my controller but am not sure how to. Any thoughts?


Solution

You can define attributes on the CustomError class just like any other error class

class CustomError < StandardError
  attr_reader :status

  def initialize(status)
    @status = status
  end
end

Here is a sample usage

begin
  raise CustomError.new(500)
rescue CustomError => e
  head(e.status)
end

If the attributes are hard-coded and do not need to be passed from where the error is raised, you can hard-code it

class CustomError < StandardError
  attr_reader :status

  def initialize
    @status = 500 # you can also define a constant instead of attribute if the value will be a constant
  end
end

That said, a word of caution for the example that you shared:

You are defining a status attribute. I am guessing this error will be raised from your model or service class and rescued in the Controller. If this is the case, consider avoiding coupling the model class to the HTTP status that the controller should return.



Answered By - Ankit
Answer Checked By - Robin (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, August 3, 2022

[FIXED] How to create page in backend via WPBakery

 August 03, 2022     backend, shortcode, visual-composer, visual-editor, wordpress     No comments   

Issue

I'm developing a plugin that creates pages for admin menu in backend via WPBakery. But when I look at generated page there is only shortcodes. How can I make plugins shortcodes execute in backend.

I've tried to use echo do_shortcode( '$content' ) but it does not work. I probably should work with plugins classes but do not know how.

I want to make a page with page builder for admin menu and execute all shortcodes that creates rows columns message boxes etc.

Any help would be appreciated.


Solution

Before using do_shortcode, add WPBMap::addAllMappedShortcodes(); function, this function loads all elements, and then do_shortcode should work fine.



Answered By - Павел Иванов
Answer Checked By - Cary Denson (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, July 13, 2022

[FIXED] Why can not I get the input of these fields? JavaScript

 July 13, 2022     backend, forms, function, javascript, web-deployment     No comments   

Issue

I have created a contact Form and I try to get the data of the name, email and message inputs trough a function when I trigger the Send Message button but the data do not print them out, are null, why?.

This is the name Field, the name class into the input enter image description here

This is the email Field, the email class into the input

enter image description here

This is the Message Field, the class message into the text area.

enter image description here

This is the function that triggers

enter image description here

This are the fields

enter image description here

And I get this when I trigger the function through the Sens Message Button.

enter image description here

Why do not store the data and print them out? Thank for you help guys.


Solution

In your trigger() function, you should change .nodeValue to .value, so you get:

function trigger() {
    let name = document.querySelector('.name').value;
    let email = document.querySelector('.email').value;
    let message = document.querySelector('.message').value;
};


Answered By - Mustard Shaper
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to return an HttpResponse object instead of None

 July 13, 2022     backend, django, python-3.x, web-deployment, web-deployment-project     No comments   

Issue

can you help me out through this problem?, I'm a beginner and trying to learn django..even tho i tried so many other ways but it just wont work out. i hope you can help me

models.py

from django.db import models
from django.db.models.fields import CharField , IntegerField, EmailField


class Member(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=50) 
    email = models.EmailField()
    age = models.IntegerField()
    password =  models.CharField(max_length=100,null=True)


    def __str__(self):
        return self.first_name + " " + self.last_name

form.py

from django.db.models import fields
from django.forms import ModelForm
from django import forms
from .models import Member



class MemberForm(forms.ModelForm):
    class Meta:
        model = Member
        fields = ["first_name", "last_name", "age", "email", "password"]

views.py

from django.shortcuts import  render
from .models import Member
from .form import MemberForm
# Create your views here.




def join(request):
    if request.method == "POST":
        form = MemberForm(request.POST or None)
        if form.is_valid():
            form.save()
            return render(request, "HTML/join.html",{})

    else:
        form = MemberForm()
        return render(request, "HTML/join.html",{})

error

The view myapp.views.join didn't return an HttpResponse object. It returned None instead.

Solution

If the form is not valid, your view must return a response:

def join(request):
    if request.method == "POST":
        form = MemberForm(data=request.POST)
        if form.is_valid():
            form.save()
            return render(request, "HTML/join.html",{})
        else:
            return HttpResponse(status=400) # Replace with what makes sense to you
    else:
        form = MemberForm()
        return render(request, "HTML/base.html", {})

In your urls write something like:

urlpatterns = [
    path('', join)
]

Note also that you should pass the form in the context parameter of render like: render(request, "HTML/base.html", {'form': form}).



Answered By - RedWheelbarrow
Answer Checked By - Mary Flores (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, July 1, 2022

[FIXED] How to add a credit card logo at the bottom of all pages of a Shopify site

 July 01, 2022     backend, e-commerce, frontend, liquid, shopify     No comments   

Issue

Reviewing our Shopify site, I realized that a major difficulty with Shopify is that it's as if the theme does everything possible to obfuscate credit card usage. The site is replete with all sorts of references to Google Pay, Amazon Pay, etc., but credit card payments are always difficult to find.

I would like to know how to add a credit card logo in the bottom of all pages and remove the default logos already there. Could you please let me know if it is possible to do it in Shopify by editing LIQUID file? If so, please point me

enter image description here


Solution

usually the page is break into 3 sections (files are stored in section folder). header.liquid , content_for_layout and footer.liquid

you can find the layout in /layout/theme.liquid

for your case, the credits icons are all in the sections/footer.liquid



Answered By - Charles C.
Answer Checked By - Candace Johnson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, June 29, 2022

[FIXED] How can I pass a button's id to an Angular function?

 June 29, 2022     angular, backend, comments, function, typescript     No comments   

Issue

I'm working on a website (basically a twitter clone), and I want to add comments to posts. To do so, I have to pass the ID of the tweet and the comment itself to the backend. So far I have the following code:

toggle(event: Event): void {
    let elementId: string = (event.target as Element).tagName;
    console.log(elementId);
    this.commentModel.value.ID = elementID;
  }

This gets called in the HTML as follows:

 <form [formGroup]="homepageservice.commentModel"
                    class="container d-flex row rounded-pill p-2 justify-content-between align-items-center w-80 addCommentBox"
                    id="add-comment" (submit)="onSendComment()">
                    <textarea type="text" name="comment" class="rounded-pill col" id="comment-input"
                        formControlName="commentcontent" placeholder="Write comment here...."></textarea>
                    <button type="submit" name={{tweet.ID}} id="addComment" class="btn btn-green rounded-pill"
                        (onclick)="homepageservice.toggle($event)">
                        <i class="bi bi-send-fill"></i>
                    </button>
                </form>

Lastly the form and the sending function:

commentModel = this.fb.group({
commentcontent: [''],
id: [''] }) 

sendComment() {
const commentText = this.commentModel.value.commentcontent;
const id = this.commentModel.value.ID;
return this.http.post(this.apiUrl + `/Tweets/newComment? 
comment=${commentText}&tweetID=${id}`, {}); }

When I run these, I get an undefined ID, and can't figure out the problem.


Solution

you can do it like this: (click)="homepageservice.toggle(tweet)" and in your service:

toggle(tweet: any) {
    console.log(tweet);
    this.commentModel.value.ID = tweet.ID;
}


Answered By - Zerotwelve
Answer Checked By - Katrina (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, May 16, 2022

[FIXED] Which hook needs to call if admin update the shipping/billing address in WooCommerce?

 May 16, 2022     backend, hook-woocommerce, orders, woocommerce, wordpress     No comments   

Issue

I'm not sure which hook/action needs to setup to know when the admin is updating shipping/billing addresses once the order has been created.

So what I'm trying to achieve here is:

  1. In WooCommerce order section when the admin updates the shipping/billing address then it triggers an action.
  2. this action basically makes a single curl call to my custom script and lets me know that the address of the order has been changed by the admin.
  3. I'll do some magic in my script.

I found below but I don't think its more from admin side.

// define the woocommerce_admin_order_data_after_shipping_address callback 
function action_woocommerce_admin_order_data_after_shipping_address( 
 $delta_wccs_custom_checkout_details_pro_shipping, $int, $int ) { 
// make action magic happen here... 
}; 
     
// add the action 
add_action( 'woocommerce_admin_order_data_after_shipping_address',  'action_woocommerce_admin_order_data_after_shipping_address', 10, 3 ); 

Please let me know if anyone knows the right action to trigger when order shipping/billing address change.


Solution

The woocommerce_admin_order_data_after_shipping_address hook is to display extra content on the order edit page (backend)


To trigger $order_item actions before or after saving to the DB, use:

/**
 * Trigger action before saving to the DB. Allows you to adjust object props before save.
 *
 * @param WC_Data          $this The object being saved.
 * @param WC_Data_Store_WP $data_store THe data store persisting the data.
 */
function action_woocommerce_before_order_item_object_save( $order_item, $data_store ) {
    // Get type
    $data_type = $order_item->get_type();

    // Before billing changes
    if ( $data_type == 'billing' ) {
        // Do..
    }

    // Before shipping changes
    if ( $data_type == 'shipping' ) {
        // Do..
    }
}
add_action( 'woocommerce_before_order_item_object_save', 'action_woocommerce_before_order_item_object_save', 10, 2 ); 

/**
 * Trigger action after saving to the DB.
 *
 * @param WC_Data          $this The object being saved.
 * @param WC_Data_Store_WP $data_store THe data store persisting the data.
 */
function action_woocommerce_after_order_item_object_save( $order_item, $data_store ) {    
    // Get type
    $data_type = $order_item->get_type();

    // After billing changes
    if ( $data_type == 'billing' ) {
        // Do..
    }

    // After shipping changes
    if ( $data_type == 'shipping' ) {
        // Do..
    }
}
add_action( 'woocommerce_after_order_item_object_save', 'action_woocommerce_after_order_item_object_save', 10, 2 ); 

OR

Use the almost identical woocommerce_before_order_object_save hook that may be even more suitable, because via $order->get_changes() you can trigger/log/compare which $order data has been changed

function action_woocommerce_before_order_object_save( $order, $data_store ) {
    // Get changes
    $changes = $order->get_changes();

    // Billing OR shipping
    if ( isset( $changes['billing'] ) || isset( $changes['shipping'] ) ) {
        // Do..
    }

    // OR even more specific (e.g.: shipping first name field was changed)
    if ( isset( $changes['shipping_first_name'] ) ) {
        // Do..
    }
}
add_action( 'woocommerce_before_order_object_save', 'action_woocommerce_before_order_object_save', 10, 2 );

EDIT: it is a known issue that these hooks are called multiple times when they are not intended to be

See: https://github.com/woocommerce/woocommerce/issues/25771

As a workaround, add:

if ( did_action( 'replace_by_the_desired_hook_name' ) >= 2 ) return;

As first line in your callback function



Answered By - 7uc1f3r
Answer Checked By - Terry (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Which hook needs to call if admin update the shipping/billing address in WooCommerce?

 May 16, 2022     backend, hook-woocommerce, orders, woocommerce, wordpress     No comments   

Issue

I'm not sure which hook/action needs to setup to know when the admin is updating shipping/billing addresses once the order has been created.

So what I'm trying to achieve here is:

  1. In WooCommerce order section when the admin updates the shipping/billing address then it triggers an action.
  2. this action basically makes a single curl call to my custom script and lets me know that the address of the order has been changed by the admin.
  3. I'll do some magic in my script.

I found below but I don't think its more from admin side.

// define the woocommerce_admin_order_data_after_shipping_address callback 
function action_woocommerce_admin_order_data_after_shipping_address( 
 $delta_wccs_custom_checkout_details_pro_shipping, $int, $int ) { 
// make action magic happen here... 
}; 
     
// add the action 
add_action( 'woocommerce_admin_order_data_after_shipping_address',  'action_woocommerce_admin_order_data_after_shipping_address', 10, 3 ); 

Please let me know if anyone knows the right action to trigger when order shipping/billing address change.


Solution

The woocommerce_admin_order_data_after_shipping_address hook is to display extra content on the order edit page (backend)


To trigger $order_item actions before or after saving to the DB, use:

/**
 * Trigger action before saving to the DB. Allows you to adjust object props before save.
 *
 * @param WC_Data          $this The object being saved.
 * @param WC_Data_Store_WP $data_store THe data store persisting the data.
 */
function action_woocommerce_before_order_item_object_save( $order_item, $data_store ) {
    // Get type
    $data_type = $order_item->get_type();

    // Before billing changes
    if ( $data_type == 'billing' ) {
        // Do..
    }

    // Before shipping changes
    if ( $data_type == 'shipping' ) {
        // Do..
    }
}
add_action( 'woocommerce_before_order_item_object_save', 'action_woocommerce_before_order_item_object_save', 10, 2 ); 

/**
 * Trigger action after saving to the DB.
 *
 * @param WC_Data          $this The object being saved.
 * @param WC_Data_Store_WP $data_store THe data store persisting the data.
 */
function action_woocommerce_after_order_item_object_save( $order_item, $data_store ) {    
    // Get type
    $data_type = $order_item->get_type();

    // After billing changes
    if ( $data_type == 'billing' ) {
        // Do..
    }

    // After shipping changes
    if ( $data_type == 'shipping' ) {
        // Do..
    }
}
add_action( 'woocommerce_after_order_item_object_save', 'action_woocommerce_after_order_item_object_save', 10, 2 ); 

OR

Use the almost identical woocommerce_before_order_object_save hook that may be even more suitable, because via $order->get_changes() you can trigger/log/compare which $order data has been changed

function action_woocommerce_before_order_object_save( $order, $data_store ) {
    // Get changes
    $changes = $order->get_changes();

    // Billing OR shipping
    if ( isset( $changes['billing'] ) || isset( $changes['shipping'] ) ) {
        // Do..
    }

    // OR even more specific (e.g.: shipping first name field was changed)
    if ( isset( $changes['shipping_first_name'] ) ) {
        // Do..
    }
}
add_action( 'woocommerce_before_order_object_save', 'action_woocommerce_before_order_object_save', 10, 2 );

EDIT: it is a known issue that these hooks are called multiple times when they are not intended to be

See: https://github.com/woocommerce/woocommerce/issues/25771

As a workaround, add:

if ( did_action( 'replace_by_the_desired_hook_name' ) >= 2 ) return;

As first line in your callback function



Answered By - 7uc1f3r
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, May 10, 2022

[FIXED] How to add / remove columns in Woocommerce admin product list

 May 10, 2022     backend, php, product, woocommerce, wordpress     No comments   

Issue

I want to customize the columns in Woocommerce admin area when viewing the product list.

Specifically, I want to remove some columns, and add several custom field columns.

I tried many solutions listed online, and I can remove columns and add new ones like this:

add_filter( 'manage_edit-product_columns', 'show_product_order',15 );
function show_product_order($columns){

   //remove column
   unset( $columns['tags'] );

   //add column
   $columns['offercode'] = __( 'Offer Code'); 

   return $columns;
}

But how do I populate the new column with the actual product data (in this case, a custom field called 'offercode')?


Solution

The filter manage_edit-{post_type}_columns is only used to actually add the column. To control what is displayed in the column for each post (product), you can use the manage_{post_type}_posts_custom_column action. This action is called for each custom column for every post, and it passes two arguments: $column and $postid.

Using this action is quite easy, you can find an example to display the custom field "offercode" below:

add_action( 'manage_product_posts_custom_column', 'wpso23858236_product_column_offercode', 10, 2 );

function wpso23858236_product_column_offercode( $column, $postid ) {
    if ( $column == 'offercode' ) {
        echo get_post_meta( $postid, 'offercode', true );
    }
}

You could also use a plugin to control this behaviour, such as Admin Columns.



Answered By - engelen
Answer Checked By - Clifford M. (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, May 8, 2022

[FIXED] How do you add custom field to woocommerce product attribute

 May 08, 2022     backend, php, product, woocommerce, wordpress     No comments   

Issue

I want to include a simple in the edit attribute form. (/wp-admin/edit.php?post_type=product&page=product_attributes&edit=55)

Is this possible? Everything i've found on SO is concerned with adding fields to products or taxonomies, if I am not wrong, product attributes are not the same as taxonomies.

I want add a custom form to my "Brand" product attribute.

Here is what I tried (with and without the pa_):

add_action('pa_brand_edit_form_fields','msp_pa_brand_form_fields');
add_action('pa_brand_add_form_fields','msp_pa_brand_form_fields');

function msp_pa_brand_form_fields () {
?>
    <tr class="form-field">
            <th valign="top" scope="row">
                <label for="display"><?php _e('Display Type', ''); ?></label>
            </th>
            <td>
                <select name="display_type">
                    <option value="select">Select</option>
                    <option value="variation_image">Variation Image w/ label</option>
                </select>
            </td>
        </tr>
        <?php 
    }

I just need help getting some html to show up on this edit screen. My overall plan is to add this select tag to every attribute, then add a piece of code into variable.php check how a attribute is to be displayed.

Any help is greatly appreciated.


Solution

With the following hooks you can add a field before or after, depending on your wishes

function action_woocommerce_before_edit_attribute_fields(  ) {
    ?>
    <tr class="form-field">
        <th valign="top" scope="row">
            <label for="display"><?php _e('Display Type', ''); ?></label>
        </th>
        <td>
            <select name="display_type">
                <option value="select">Select</option>
                <option value="variation_image">Variation Image w/ label</option>
            </select>
        </td>
    </tr>
    <?php
}
add_action( 'woocommerce_before_edit_attribute_fields', 'action_woocommerce_before_edit_attribute_fields', 10, 0 ); 
 
function action_woocommerce_after_edit_attribute_fields(  ) {
    ?>
    <tr class="form-field">
        <th valign="top" scope="row">
            <label for="display"><?php _e('Display Type', ''); ?></label>
        </th>
        <td>
            <select name="display_type">
                <option value="select">Select</option>
                <option value="variation_image">Variation Image w/ label</option>
            </select>
        </td>
    </tr>
    <?php
}
add_action( 'woocommerce_after_edit_attribute_fields', 'action_woocommerce_after_edit_attribute_fields', 10, 0 );


Answered By - 7uc1f3r
Answer Checked By - Robin (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, April 27, 2022

[FIXED] How to fix unhandled promise rejection warning in NestJS

 April 27, 2022     angular, backend, nestjs, typescript, warnings     No comments   

Issue

I'm using NestJS for my backend angular project and I've put method. It was running fine before I install swagger but after I install swagger, I got a warning that saying unhandled promise rejection and it won't allow me to run.

It's working fine If I comment the code in controllers so I think there is a problem with async/await but not really sure how to fix it so I would be really appreciated if I can get any help or suggestion on how to fix this?

Controller

    @Put(':id')
    async updateHelpSubsection(@Body() newHelp: HelpSubsectionModule, @Param() params): Promise<HelpSubsectionModule> {
        try{
            let oldHelpData = await this.helpSubsectionService.getHelpSubsectionbyId(params.id)
            return this.helpSubsectionService.updateHelpSubsection(oldHelpData, newHelp);
        }catch(e) {
            console.log(e)
        }
    }

Services

    async updateHelpSection(updateHelp: HelpSectionEntity, newHelpData): Promise<HelpSectionEntity> {

        Object.keys(newHelpData).forEach((key) => {
            updateHelp[key] = newHelpData[key];
        });

        try {
            return await this.helpSectionRepo.save(updateHelp);
        } catch (err) {
            throw new HttpException({
                error: err
            }, HttpStatus.FORBIDDEN)
        }
    }

This is the warning I'm getting. enter image description here


Solution

Please update this in the controller:

       @Put(':id')
       async updateHelpSubsection(@Body() newHelp: HelpSectionEntity, @Param() params): Promise< HelpSectionEntity> {
           try{
               let oldHelpData = await this.helpSubsectionService.getHelpSubsectionbyId(params.id)
               return this.helpSubsectionService.updateHelpSubsection(oldHelpData, newHelp);
           }catch(e) {
               console.log(e)
           }
       }

Modules are not allowed in the types in typescript.

Please replace HelpSubsectionModule with HelpSectionEntity.



Answered By - Praveen Kumar Palai
Answer Checked By - Mary Flores (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, March 3, 2022

[FIXED] How to get result from database based on the user with laravel

 March 03, 2022     backend, eloquent, laravel-5, php     No comments   

Issue

I started coding laravel and everything was fine till I wanted to get the result based on the user, how to do it, what do I need to do?.


Solution

You can use where clause.

Suppose you wanna fetch all the blogs of a user.

like:

Blog::where('user_id', Auth::user()->id)->get();

// Auth::user()->id returns the logged in user's id.

Or

create a relation in User model

App\Models\User
use App\Models\Blog;

 public function blogs()
 {
     return $this->hasMany(User::class, 'user_id', 'id');
 }

Then

Auth::user()->blogs;


Answered By - Aniket Das
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, February 16, 2022

[FIXED] Laravel pagination not working with tailwindcss

 February 16, 2022     backend, laravel, pagination, php, tailwind-css     No comments   

Issue

This is my controller file's index function

 public function index()
        {
            $projects = Projects::All()->paginate( 5 );
            return view('projects.index')->with('projects', $projects);
        }

And, This is my blade file's pagination code

@foreach ($projects as $project)

{{ $project->links('pagination::tailwind') }}

@endforeach

But, Still, there's an error, that is saying

BadMethodCallException
Method Illuminate\Database\Eloquent\Collection::paginate does not exist. 

Solution

You have a typo. This is not correct:

{{ $project->links('pagination::tailwind') }}

Error 1: You are missing a 's':

{{ $projects->links() }}

Error 2: You do not have to put your links in the loop but outside the loop. normaly after the loop.

@foreach($records as $record)
{{ $record->field }}
@endforeach
{{ $records->links() }}

Suggestion: I prefer to tell laravel which paginator I am using in this file: App/Providers/AppServiceProvider.php

public function boot()
{
    Paginator::useBootstrap(); //bootstrap in this case
}

For tailwind, there is no need to specify anything, since it is the default.



Answered By - M. Saba
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, February 12, 2022

[FIXED] Display user description in WooCommerce admin order edit pages after billing address

 February 12, 2022     backend, hook-woocommerce, orders, woocommerce, wordpress     No comments   

Issue

I need to display customer Bio in WooCommerce admin order edit pages after the billing address.

Actually I only succeeded to display in a column like that:

column

With this code:

 // Adding a custom new column to admin orders list
add_filter( 'manage_edit-shop_order_columns', 'custom_column_eldest_players', 20 );
function custom_column_eldest_players($columns)
{
    $reordered_columns = array();

    // Inserting columns to a specific location
    foreach( $columns as $key => $column){
        $reordered_columns[$key] = $column;
        if( $key ==  'order_status' ){
            // Inserting after "Status" column
            $reordered_columns['user-bio'] = __( 'Note client', 'woocommerce');
        }
    }
    return $reordered_columns;
}

// Adding custom fields meta data for the column
add_action( 'manage_shop_order_posts_custom_column' , 'custom_orders_list_column_content', 20, 2 );
function custom_orders_list_column_content( $column, $post_id ) {
    if ( 'user-bio' === $column ) {
        global $the_order;

        echo ( $user = $the_order->get_user() ) ? $user->description : 'n/c';
    }
}

But I don't know how to insert in WooCommerce admin order edit pages. Any advice?


Solution

Do display the user description on the admin order pages after billing adress you can use the woocommerce_admin_order_data_after_billing_address acton hook.

So you get:

// Display on admin order pages after billing adress
function action_woocommerce_admin_order_data_after_billing_address( $order ) {  
    // Get user
    $user = $order->get_user();
    
    // Initialize
    $output = __( 'Bio: ', 'woocommerce' );

    // Is a WP user
    if ( is_a( $user, 'WP_User' ) ) {
        ! empty( $user->description ) ? $output .= $user->description : $output .= __( 'n/c', 'woocommerce' );
    } else {
        $output .= __( 'n/c', 'woocommerce' );
    }
    
    // Output
    echo $output;
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'action_woocommerce_admin_order_data_after_billing_address', 10, 1 );


Answered By - 7uc1f3r
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing