<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Oliver Kem</title>
    <description>The latest articles on DEV Community by Oliver Kem (@olivermengich).</description>
    <link>https://dev.to/olivermengich</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F325466%2F24059c68-1c19-487b-8458-95fcba2c3198.png</url>
      <title>DEV Community: Oliver Kem</title>
      <link>https://dev.to/olivermengich</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/olivermengich"/>
    <language>en</language>
    <item>
      <title>tRPC APIs - Part 2</title>
      <dc:creator>Oliver Kem</dc:creator>
      <pubDate>Sun, 30 Jul 2023 14:49:19 +0000</pubDate>
      <link>https://dev.to/olivermengich/trpc-apis-part-2-4ci0</link>
      <guid>https://dev.to/olivermengich/trpc-apis-part-2-4ci0</guid>
      <description>&lt;h1&gt;
  
  
  Hello everyone!
&lt;/h1&gt;

&lt;p&gt;welcome back, in our &lt;a href="https://dev.to/olivermengich/trpc-apis-part-1-4oho"&gt;first session&lt;/a&gt; we had implemented our backend server of the tRPC apis where we built a simple server that fetches books from some datasource and returns that in json format. We also tested our aplication and it worked fine. In this section, we are going to build our frontend that interacts with our backend server, fetches data and displays it in our app. To do this, I will be building a simple React application using vite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Part 1 of our &lt;a href="https://dev.to/olivermengich/trpc-apis-part-1-4oho"&gt;session&lt;/a&gt;. Feel free to build your own&lt;/li&gt;
&lt;li&gt;Typescript&lt;/li&gt;
&lt;li&gt;React knowledge&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let us begin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From&lt;/strong&gt; our introduction, we mentioned that tRPC implements typesafe Remote Procedural Call and this basically means it allows a machine from one side to call another procedure or function from another machine. The typesafe bit means it leverages typescript for typesafety. This helps in code building and productivity boost during application development. Let us start developing our application&lt;br&gt;
We had created a folder where we put two folders, &lt;code&gt;trpc-backend&lt;/code&gt; and &lt;code&gt;trpc-frontend&lt;/code&gt;. For now, navigate to the frontend folder and run the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pnpm vite@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the prompt, I will also be using typescript. You should be getting something like this in the folder. However, feel free to develop it how you like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hinqvh5e2n69xjwjavk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hinqvh5e2n69xjwjavk.png" alt="Landing"&gt;&lt;/a&gt;&lt;br&gt;
Now let us continue with development, I will be using &lt;code&gt;TailwindCSS&lt;/code&gt; for some styling and &lt;code&gt;React Query&lt;/code&gt; for our state management. So let us initialize our application with tailwind.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pnpm add -D tailwindcss  postcss autoprefixer
$ npx tailwindcss init -p
$ pnpm add react-query 
$ pnpm add @trpc/client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, let us to our &lt;code&gt;index.css&lt;/code&gt; file, comment all the code add the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@tailwind base;
@tailwind components;
@tailwind utilities;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the code in the&lt;br&gt;
&lt;br&gt;
 `&lt;code&gt;tailwind.config.js&lt;/code&gt; with this&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now our application can use TailwindCSS.&lt;br&gt;
In our &lt;code&gt;&lt;br&gt;
&lt;br&gt;
main.tsx&lt;br&gt;
&lt;br&gt;
&lt;/code&gt; file, we need to wrap with &lt;code&gt;react-query&lt;/code&gt; to make our state available for every component, to do so, paste the following&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import App from './App.tsx'
import './index.css'
import { QueryClient, QueryClientProvider, } from 'react-query';
const queryClient = new QueryClient();

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;QueryClientProvider client={queryClient}&amp;gt;
    &amp;lt;App /&amp;gt;
&amp;lt;/QueryClientProvider&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;,
)



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now &lt;code&gt;react-query&lt;/code&gt; will be available for our application.&lt;br&gt;
Now let us go to our &lt;code&gt;App.tsx&lt;/code&gt; file and add the following. &lt;/p&gt;

&lt;p&gt;Here is where we will handle the state logic and the fetching logic. &lt;code&gt;tRPC&lt;/code&gt; changed alot from version 9. So the documentation for integrating with react also changed.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { AppRouter } from '../../trpc-backend/src/trpc/trpc';
import { createTRPCProxyClient, httpBatchLink} from '@trpc/client'
function App(){
    const trpcClient= createTRPCProxyClient&amp;lt;AppRouter&amp;gt;({
        links:[
            httpBatchLink({
                url: 'http://localhost:3000/trpc',
            }),
        ]
    });
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let us go through this, here we imported the &lt;code&gt;&lt;br&gt;
&lt;br&gt;
AppRouter&lt;br&gt;
&lt;br&gt;
&lt;/code&gt; type we had exported from our backend server, then we import the &lt;code&gt;httpBatchLink&lt;/code&gt; and &lt;code&gt;createTRPCProxyClient&lt;/code&gt; from the client library. We then set the link to the backend server and that is it. Now are ready to interact with our server data.&lt;br&gt;
Next we import the functions that help up query&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import {  useMutation, useQuery, useQueryClient } from 'react-query';
import { AppRouter } from '../../trpc-backend/src/trpc/trpc';
import { createTRPCProxyClient, httpBatchLink} from '@trpc/client'
type Book={
    id: number,
    title: string,
    img: string,
    description: string,
    price: number
    author: string
}
function App(){
    const {data,isLoading, isError,} = useQuery({
        queryKey: ['books'],
        queryFn: async () =&amp;gt; await trpcClient.getBooks.query(),

    })
    const trpcClient= createTRPCProxyClient&amp;lt;AppRouter&amp;gt;({
        links:[
            httpBatchLink({
                url: 'http://localhost:3000/trpc',
            }),
        ]
    });
   if(isLoading) return &amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;
   if(isError) return &amp;lt;div&amp;gt;Error&amp;lt;/div&amp;gt;
   return (
        &amp;lt;div&amp;gt;
            &amp;lt;h1 className="text-3xl font-bold"&amp;gt;React tRPC and react query&amp;lt;/h1&amp;gt;

            &amp;lt;div className='grid grid-cols-2 gap-1 md:grid md:grid-cols-3 md:gap-2'
            &amp;gt;
                {
                    data?.map((item: Book)=&amp;gt;{
                        return (
                            &amp;lt;div key={item.id} className='border-2 border-gray-200 rounded-md p-2 hover:bg-sky-500 transition ease-in-out delay-150'&amp;gt;
                                &amp;lt;img src={item.img} alt={item.title} className='w-32 h-32'/&amp;gt;
                                &amp;lt;h2 className='text-xl font-bold'&amp;gt;{item.title}&amp;lt;/h2&amp;gt;
                                &amp;lt;p className='text-sm'&amp;gt;{item.description.slice(0,50)}...&amp;lt;/p&amp;gt;
                                &amp;lt;p className='text-sm font-bold'&amp;gt;${item.price}&amp;lt;/p&amp;gt;
                            &amp;lt;/div&amp;gt;

                        )
                    })
                }
            &amp;lt;/div&amp;gt;          
        &amp;lt;/div&amp;gt;
    )
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this code, we have just&lt;/p&gt;

</description>
      <category>trpc</category>
      <category>api</category>
      <category>vite</category>
      <category>frontend</category>
    </item>
    <item>
      <title>tRPC APIs - Part 1</title>
      <dc:creator>Oliver Kem</dc:creator>
      <pubDate>Tue, 20 Jun 2023 11:15:48 +0000</pubDate>
      <link>https://dev.to/olivermengich/trpc-apis-part-1-4oho</link>
      <guid>https://dev.to/olivermengich/trpc-apis-part-1-4oho</guid>
      <description>&lt;h1&gt;
  
  
  Hello Devs.
&lt;/h1&gt;

&lt;p&gt;When it comes to APIs, the first thing that comes to your mind is RESTful and GraphQL APIs. While these two powers the modern web communication, there's this new talk in town, tRPC (&lt;strong&gt;typesafe Remote Procedure Call&lt;/strong&gt;). This is a framework for writing APIs meaning it offers all advantages of REST and GraphQL APIs are more such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type safely for both client and server. &lt;/li&gt;
&lt;li&gt;Abstraction on schema&lt;/li&gt;
&lt;li&gt;Secure Connection from client to server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and more....&lt;br&gt;
What do you mean 🤔🤔🤔🤔🤔🤔🤔? Check this out. Let's start with how APIs changed the world&lt;/p&gt;
&lt;h4&gt;
  
  
  Rest APIs
&lt;/h4&gt;

&lt;p&gt;When rest APIs came, they provided a means of fetching and push data from the server to client fast, lightweight and easier because data was sent and retrieved in JSON format. But as applications grew, there as need of a predefined way or schema where people could know exactly what they are fetching and they could filter what they could fetch from the server because Rest APIs returns alot of information &lt;strong&gt;(over fetching)&lt;/strong&gt; or little information &lt;strong&gt;(under fetching)&lt;/strong&gt; which in most cases is unnecessary&lt;/p&gt;
&lt;h4&gt;
  
  
  GraphQL
&lt;/h4&gt;

&lt;p&gt;In 2012, Facebook started developing GraphQL to address the major concerns of Rest APIs and solve on scalability of their applications, at first it was developed to be used internally until 2015 where they released it to the Public (open source). This got the community so much involved in the project that they started contributing to the GraphQL project and developed libraries like ApolloGraphQL, GraphQL Yoga, Express GraphQL e.t.c. And while GraphQL solved alot of problems, the whole idea of defining a schema for requests was somehow hectic. When your application starts to scale you'll need to create each schema for each request and resource you want to fetch.&lt;/p&gt;
&lt;h4&gt;
  
  
  tRPC
&lt;/h4&gt;

&lt;p&gt;tRPC mean *&lt;em&gt;TypeSafe - Remote Procedure Call *&lt;/em&gt;. RPC mean *** remote procedure call ** this basically means allowing a machine or device from one device to call a function from another PC or machine. When you at typesafe, this maintains type safety between the (one machine)client and (other machine)server such that you can develop your application safely and easily.&lt;/p&gt;

&lt;p&gt;Let's begin. We will start by creating our backend. So, go to your terminal and run the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir trpc
$ cd trpc
$ mkdir trpc-backend
$ cd trpc-backend

$pnpm init -y
$ code .

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let us install a couple of dependencies, &lt;code&gt;express&lt;/code&gt;, &lt;code&gt;@trpc/server&lt;/code&gt;, &lt;code&gt;zod&lt;/code&gt; &lt;code&gt;cors&lt;/code&gt;. I will also be using typescript, so let us install some types library &lt;code&gt;@types/node&lt;/code&gt;, &lt;code&gt;@types/express&lt;/code&gt;, &lt;code&gt;nodemon&lt;/code&gt;, &lt;code&gt;typescript&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pnpm add express zod cors @trpc/server
$ pnpm add -D @types/node @types/express nodemon typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6qowwnnuofa8fqoe2zqx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6qowwnnuofa8fqoe2zqx.png" alt="Project setup" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, from this image, we will initialize our application, set your package.json to look exactly like mine.&lt;br&gt;
Now make a root directory called &lt;code&gt;src&lt;/code&gt;. Then inside, create two directories &lt;code&gt;data&lt;/code&gt; and &lt;code&gt;trpc&lt;/code&gt;. Inside the data, create an &lt;code&gt;index.ts&lt;/code&gt; file, then paste the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const books=[
    {
        id:1,
        title:"The Lord of the Rings",
        author: "J.R.R. Tolkien",
        price: 20,
        img: "https://images-na.ssl-images-amazon.com/images/I/51UoqRAxwEL._SX331_BO1,204,203,200_.jpg",
        description: "The Lord of the Rings is an epic high fantasy novel by the English author and scholar J. R. R. Tolkien. Set in Middle-earth, the world at some distant time in the past, the story began as a sequel to Tolkien's 1937 children's book The Hobbit, but eventually developed into a much larger work. Written in stages between 1937 and 1949, The Lord of the Rings is one of the best-selling books ever written, with over 150 million copies sold."
    },
    {
        id:2,
        title:"The Hobbit",
        author: "J.R.R. Tolkien",
        price: 15,
        img: "https://images-na.ssl-images-amazon.com/images/I/51o5n%2B1Q%2BtL._SX331_BO1,204,203,200_.jpg",
        description: "The Hobbit, or There and Back Again is a children's fantasy novel by English author J. R. R. Tolkien. It was published on 21 September 1937 to wide critical acclaim, being nominated for the Carnegie Medal and awarded a prize from the New York Herald Tribune for best juvenile fiction. The book remains popular and is recognized as a classic in children's literature."
    },
    {
        id:3,
        title:"The Silmarillion",
        price: 25,
        author: "T.B Tolkien",
        img: "https://images-na.ssl-images-amazon.com/images/I/51Q5ZQ%2BZ1TL._SX331_BO1,204,203,200_.jpg",
        description: "The Silmarillion is a collection of mythopoeic works by English writer J. R. R. Tolkien, edited and published posthumously by his son, Christopher Tolkien, in 1977, with assistance from Guy Gavriel Kay. The Silmarillion, along with J. R. R. Tolkien's other works, forms an extensive, though incomplete, narrative that describes the universe of Eä in which are found the lands of Valinor, Beleriand, Númenor, and Middle-earth, within which The Hobbit and The Lord of the Rings take place."
    },
    {
        id:4,
        title:"The Children of Húrin",
        price: 30,
        author: "J.R.R. Tolkien",
        img: "https://images-na.ssl-images-amazon.com/images/I/51Q5ZQ%2BZ1TL._SX331_BO1,204,203,200_.jpg",
        description: "The Children of Húrin is an epic fantasy novel which forms the completion of a tale by J. R. R. Tolkien. He wrote the original version of the story in the late 1910s, revised it several times later, but did not complete it before his death in 1973. His son, Christopher Tolkien, edited the manuscripts to form a consistent narrative, and published it in 2007 as an independent work."

    },
];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will be using this as our dummy database data. Feel free to add some database functionality to retrieve and add data. &lt;br&gt;
Now, inside the &lt;code&gt;trpc&lt;/code&gt; folder we created, add a file called &lt;code&gt;trpc.ts&lt;/code&gt;, then paste the following lines of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { initTRPC } from "@trpc/server";
import {z} from 'zod';
import { books } from "../data/index.ts";
const t  = initTRPC.create()
const publicProcedure = t.procedure;

export const appRouter = t.router({
    greeting: publicProcedure
        .query(()=&amp;gt;{
            return "Hello World"
        }),
    getBooks: publicProcedure
        .query(()=&amp;gt;{
            return books;
        }),
    fetchABook: publicProcedure
        .input(z.object({
            id: z.number(),
        }))
        .query(({input})=&amp;gt;{
            console.log(input);
            const book =  books.find((book)=&amp;gt;book.id === input.id)
            console.log(book);
            return book;
        }),
    addABook: publicProcedure
        .input(z.object({
            title: z.string(),
            id: z.number(),
            author: z.string(),
            description: z.string(),
            price: z.number(),
            img: z.string(),
        }))
        .mutation(({input})=&amp;gt;{
            books.push({
                title: input.title,
                id: input.id,
                img: input.img,
                description: input.description,
                price: input.price,
                author: input.author,
            });
            return input;
        }),

})
export type AppRouter = typeof appRouter;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From above, we have initialized trpc with &lt;code&gt;initTRPC&lt;/code&gt;, we have then used &lt;code&gt;zod&lt;/code&gt; as an input validator, we will use this to validate our inputs before executing a query.&lt;br&gt;
Now, let us test our application.&lt;br&gt;
Go to your terminal and run the following.&lt;br&gt;
Now, we need to have a wrapper that will be our web server to hosting our API. Inside the &lt;code&gt;src&lt;/code&gt; folder, create a file called &lt;code&gt;index.ts&lt;/code&gt; add the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { appRouter, } from "./trpc/trpc.ts";
import express from 'express';
import * as trpExpress from '@trpc/server/adapters/express';
import cors from 'cors';
const app = express();
app.use(cors());
app.use(express.json());
app.use('/trpc',
    trpExpress.createExpressMiddleware({
        router: appRouter,
        createContext: ({req,res}) =&amp;gt; {
            const token = req.headers.authorization;

            return {
                // this is where you would put your auth, db, etc...
            }
        },

    })
);
app.get('/',(req,res)=&amp;gt;{
    return res.json({message:"Hello World"});
});
app.listen(3000,()=&amp;gt;{
    console.log("Server started on port 3000");
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From above, we have just imported the server instance we created. Now we use the express adapters, we use express for our backend instance, you can use other wrappers like &lt;code&gt;NextJS&lt;/code&gt;, if you are building a nextJS application. We use &lt;code&gt;cors&lt;/code&gt; to help query to our backend instance. Now with this, let us start.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pnpm dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can use postman or your browser to test the endpoints.&lt;br&gt;
Go to &lt;code&gt;https//localhost:3000/trpc/greeting&lt;/code&gt; on your browser. You should get the following response&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fov9mxz8ivu559kjpwk14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fov9mxz8ivu559kjpwk14.png" alt="Request Output" width="800" height="449"&gt;&lt;/a&gt;&lt;br&gt;
IF you get this, it means your backend server is successfully running. Now with this, you are good to go. I will be continuing with part two.&lt;/p&gt;

</description>
      <category>career</category>
      <category>productivity</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>Connecting React Native App to Crypto Wallet.</title>
      <dc:creator>Oliver Kem</dc:creator>
      <pubDate>Sat, 17 Jun 2023 13:00:56 +0000</pubDate>
      <link>https://dev.to/olivermengich/connecting-react-native-app-to-crypto-wallet-41nj</link>
      <guid>https://dev.to/olivermengich/connecting-react-native-app-to-crypto-wallet-41nj</guid>
      <description>&lt;p&gt;Hello everyone, 👋, in this blog, I will show you how you can connect your React Native application to a wallet on your phone, you might be building an application where you need a user to pay with cryptocurrency in their wallet or you want a user to authenticate using their wallet address, well , you have come to the right place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;React Native knowledge&lt;/li&gt;
&lt;li&gt;Javascript&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's begin, we start by creating a new react native application, I will be using Expo but feel free to switch to using the CLI, go to your terminal and create a React Native application&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx create-expo-app MyApp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the prompt if there is any then initialize a new application.&lt;br&gt;
Then we open the installation in VSCODE.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$cd MyApp
$code .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you Open the Application, you'll be greeted by page showing all elements.&lt;/p&gt;

&lt;p&gt;Let us change our &lt;code&gt;App.js&lt;/code&gt; file and we add a few elements and styling, paste the following lines of code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { StatusBar } from 'expo-status-bar';
import './global';
import { StyleSheet, ImageBackground,SafeAreaView, Platform,View } from 'react-native';
import React, { useState } from 'react';
import MainPage from './screens/MainPage';
import WalletConnectProvider from "@walletconnect/react-native-dapp";
import AsyncStorage from "@react-native-async-storage/async-storage";
const SCHEME_FROM_APP_JSON = "walletconnect-example";

export default function App() {
    let screen = &amp;lt;MainPage/&amp;gt;;
    return (
        &amp;lt;&amp;gt;
            &amp;lt;StatusBar style="dark" /&amp;gt;
            &amp;lt;ImageBackground style={{flex:1}} imageStyle={{opacity: .5}} resizeMode='cover' source={require('./assets/background.jpg')}&amp;gt;
                &amp;lt;SafeAreaView style={styles.container}&amp;gt;
                    &amp;lt;WalletConnectProvider
                        redirectUrl={
                            Platform.OS === "web"
                            ? window.location.origin
                            : `${SCHEME_FROM_APP_JSON}://`
                        }
                        storageOptions={{
                            asyncStorage: AsyncStorage,
                        }}
                        &amp;gt;
                        &amp;lt;View style={styles.container}&amp;gt;
                            {/* &amp;lt;StatusBar style="auto" /&amp;gt; */}
                            {screen}
                            {/* &amp;lt;WalletConnectExperience functionStateHandler={functionStateHandler} /&amp;gt; */}
                        &amp;lt;/View&amp;gt;
                    &amp;lt;/WalletConnectProvider&amp;gt;
                &amp;lt;/SafeAreaView&amp;gt;
            &amp;lt;/ImageBackground&amp;gt;
        &amp;lt;/&amp;gt;
    );
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
    },
    backgroundImage:{
        // opacity: .15,
        flex:1,
        // backgroundColor:'rgba(0,0,0,.5)'
    }
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, I have wrapped the main page with the &lt;code&gt;WalletConnectProvider&lt;/code&gt;. We will see this later in action&lt;br&gt;
Now let's create a &lt;code&gt;components&lt;/code&gt; folder and then we create a component called &lt;code&gt;Button.component.jsx&lt;/code&gt;. Inside the file, paste the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import { StyleSheet, Text, View, Pressable } from 'react-native';
function Button({children,onPress, widthSet}) {
    return (
        &amp;lt;View style={[styles.buttonOuterContainer,{width: widthSet,}]}&amp;gt;
            &amp;lt;Pressable
                style={({ pressed }) =&amp;gt;
                    pressed
                        ? [styles.pressed, styles.button_Inner_container]
                        : styles.button_Inner_container
                }
                android_ripple={{ color: '#6CA9F9' }}
                onPress={onPress}
            &amp;gt;
                &amp;lt;Text style={styles.buttonText}&amp;gt;{children}&amp;lt;/Text&amp;gt;
            &amp;lt;/Pressable&amp;gt;
        &amp;lt;/View&amp;gt;
    );
}
const styles = StyleSheet.create({
    button_Inner_container: {
        backgroundColor: '#4E97F5',

        paddingVertical: 16,
        paddingHorizontal: 16,
        elevation: 4,
    },
    buttonOuterContainer: {

        margin: 4,
        borderRadius: 1,
        overflow: "hidden",
    },
    buttonText: {
        color: "#fff",
        textAlign: "center",
    },
    pressed: {
        opacity: 0.75,
    },
});
export default Button;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have just added a button and styled it. Nothing fancy at all.&lt;br&gt;
...&lt;br&gt;
Now, let's create a folder called &lt;code&gt;screens&lt;/code&gt; and the we add a page called &lt;code&gt;MainPage.jsx&lt;/code&gt;, let us install a library&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; $ npm install react-native-dropdown-picker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the mainpage, paste the following lines of code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React,{useEffect} from 'react';
import { StyleSheet,TouchableOpacity, Text,FlatList, View, Dimensions, TextInput, ScrollView, Alert } from 'react-native';
import {Dropdown} from 'react-native-element-dropdown';
import { AntDesign } from '@expo/vector-icons';
import ButtonComponent from '../components/Button.component.jsx'
function MainPage() {
    const { height } = Dimensions.get('window');
    const connector = useWalletConnect();
    const [isFocus, setIsFocus] = React.useState(false);
    const [value, setValue] = React.useState({wallet:0, amount:0, receiver: ''});
    const [transactionHistory,setTransactionHistory] = React.useState([]);
    const [ownerAddress,setOwnerAddress] = React.useState('');




    return (
        &amp;lt;View style={{flex:1,marginTop:height*.09,position:'relative'}}&amp;gt;
            &amp;lt;View  style={{flexDirection:'row',alignItems:'center',justifyContent: 'space-between',marginHorizontal:7 }}&amp;gt;
                &amp;lt;View style={{flexDirection:'row', alignItems:'center'}}&amp;gt;
                    &amp;lt;Text style={styles.boldText}&amp;gt;Total Sent:&amp;lt;/Text&amp;gt;
                    &amp;lt;Text style={styles.boldText}&amp;gt;0 BTC&amp;lt;/Text&amp;gt;
                &amp;lt;/View&amp;gt;
                &amp;lt;View style={{flexDirection:'row', alignItems:'center'}}&amp;gt;

                        &amp;lt;&amp;gt;
                          &amp;lt;Text style={styles.boldText}&amp;gt;Wallet Address&amp;lt;/Text&amp;gt;
                             &amp;lt;ButtonComponent widthSet={'20%'} onPress={()=&amp;gt;{}} &amp;gt;Log out&amp;lt;/ButtonComponent&amp;gt;
                       &amp;lt;/&amp;gt;

                &amp;lt;/View&amp;gt;
            &amp;lt;/View&amp;gt;
            &amp;lt;Text style={[styles.boldText,{marginTop:height*.04, textAlign:'center'}]}&amp;gt; Send only 5 BTC per transaction&amp;lt;/Text&amp;gt;

            &amp;lt;Dropdown
                style={[styles.dropdown, isFocus &amp;amp;&amp;amp; { borderColor: '#000' }]}
                placeholderStyle={styles.placeholderStyle}
                selectedTextStyle={styles.selectedTextStyle}
                inputSearchStyle={styles.inputSearchStyle}
                iconStyle={styles.iconStyle}
                data={[
                    { label: "Blockchain", value: 1},
                    {label:"Trust Wallet",value: 2},
                    {label:"Binance",value: 3},
                ]}
                search
                maxHeight={300}
                labelField="label"
                valueField="value"
                placeholder={!isFocus ? 'Select Account' : '...'}
                searchPlaceholder="Search..."
                value={value.wallet}
                onFocus={() =&amp;gt; setIsFocus(true)}
                onBlur={() =&amp;gt; setIsFocus(false)}
                onChange={item =&amp;gt; {
                    setValue({wallet: item.value});
                    setIsFocus(false);
                }}
                renderLeftIcon={() =&amp;gt; (
                    &amp;lt;AntDesign style={styles.icon}
                        color={isFocus ? '#fff' : 'black'}
                        name="Safety"
                        size={20}
                    /&amp;gt;
                )}
            /&amp;gt;
            &amp;lt;View style={{marginTop:height*.04,alignItems:'center',flexDirection:'row'}}&amp;gt;
                &amp;lt;Text style={styles.boldText} &amp;gt;Receiver's Wallet:&amp;lt;/Text&amp;gt;
                &amp;lt;TextInput keyboardType='twitter' 
                    style={[styles.textInput,{width:'70%'}]} 
                    placeholder="0.00000000" 

                /&amp;gt;
            &amp;lt;/View&amp;gt;
            &amp;lt;View style={{marginTop:height*.04,justifyContent:'space-evenly',alignItems:'center',flexDirection:'row'}}&amp;gt;
                &amp;lt;Text style={styles.boldText}&amp;gt;BTC Amount&amp;lt;/Text&amp;gt;
                &amp;lt;TextInput keyboardType='number-pad' 
                    style={styles.textInput} 
                    placeholder="0.00000000" 

                /&amp;gt;
                &amp;lt;Button widthSet={'20%'} label={'Send'}/&amp;gt;
            &amp;lt;/View&amp;gt;
            &amp;lt;View style={{marginTop:height*.04,marginHorizontal:height*.04}}&amp;gt;
                &amp;lt;View style={{flexDirection:'row', justifyContent:'space-between',borderBottomWidth:1,paddingVertical:10}}&amp;gt;
                    &amp;lt;Text style={styles.boldText}&amp;gt;History&amp;lt;/Text&amp;gt;
                    &amp;lt;Text style={styles.boldText}&amp;gt;Clear&amp;lt;/Text&amp;gt;
                &amp;lt;/View&amp;gt;
                &amp;lt;ScrollView style={{height: height*.2}}&amp;gt;
                    &amp;lt;FlatList
                        data={transactionHistory}
                        renderItem={({ item }) =&amp;gt; (
                            &amp;lt;View style={{flexDirection:'row',justifyContent:'space-between',paddingVertical:10}}&amp;gt;
                                &amp;lt;Text style={styles.normalText}&amp;gt;{item.date}&amp;lt;/Text&amp;gt;
                                &amp;lt;Text style={styles.normalText}&amp;gt;{item.amount}&amp;lt;/Text&amp;gt;
                            &amp;lt;/View&amp;gt;
                        )}
                        keyExtractor={item =&amp;gt; item.id}
                    /&amp;gt;
                &amp;lt;/ScrollView&amp;gt;
            &amp;lt;/View&amp;gt;
            &amp;lt;View style={{position:'absolute',bottom:30}}&amp;gt;
                &amp;lt;Text style={[styles.boldText,{textAlign:'center',fontSize:20}]}&amp;gt;Need to Know&amp;lt;/Text&amp;gt;
                &amp;lt;Text style={styles.normalText}&amp;gt;1. Transactions will get 6 confirmations on the Blockchain&amp;lt;/Text&amp;gt;
                &amp;lt;Text style={styles.normalText}&amp;gt;2. Transactions stays for only 45 days before becoming invalid&amp;lt;/Text&amp;gt;
                &amp;lt;Text style={styles.normalText}&amp;gt;3. Transactions takes 20-30mins&amp;lt;/Text&amp;gt;
            &amp;lt;/View&amp;gt;
        &amp;lt;/View&amp;gt;
    );
}
const styles = StyleSheet.create({
    rowContainer: {
        backgroundColor: '#4E97F5',
    },
    textInput:{
        borderBottomWidth:.5,
        // ,
        // paddingHorizontal:10,
        // paddingVertical: 16,
        paddingHorizontal: 16,
    },
    boldText:{
        fontWeight:'bold',
        fontSize:16, 
    },
    normalText:{
        fontSize:16,
    },
    icon: {
        marginRight: 5,
    },
    placeholderStyle: {
        fontSize: 16,
    },
    selectedTextStyle: {
        fontSize: 16,
    },
    iconStyle: {
        width: 20,
        height: 20,
    },
    inputSearchStyle: {
        height: 40,
        fontSize: 16,
    },
    button: {
        backgroundColor: "#5A45FF",
        color: "#FFFFFF",
        borderRadius: 2,
        paddingHorizontal: 16,
        paddingVertical: 12,
    },
    text: {
        color: "#FFFFFF",
        fontSize: 16,
        fontWeight: "600",
    },
    dropdown: {
        height: 50,
        borderColor: '#000',
        borderBottomWidth: 0.5,
        paddingHorizontal: 8,
        marginVertical: 20,
    },
});
export default MainPage;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you implement this, you will get a nice design as shown below. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F65ectad4cbcoxw18r9hi.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F65ectad4cbcoxw18r9hi.jpeg" alt="MainPage"&gt;&lt;/a&gt;&lt;br&gt;
//=====================image===========================//&lt;br&gt;
Now, let us install a couple of dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx expo install @react-native-async-storage/async-storage @walletconnect/client @walletconnect/react-native-dapp

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After you have done this we do this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install react-native-get-random-values@1.8.0 react-native-randombytes@3.6.1 react-native-crypto@2.2.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After successfully installing this, we need to do a small thing. In the package.json file, let's add a script to be executed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    "postinstall": "rn-nodeify --hack --install process,crypto,events,constant,console,stream,url,util"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is very essential because the&lt;br&gt;
&lt;br&gt;
  `&lt;code&gt;@wallectconnect/react-native-dapp&lt;/code&gt; needs crypto module which is only native to NodeJS and not React Native, running this will include it to your application.&lt;/p&gt;

&lt;p&gt;Now let's finish up on the frontend functionality by adding the following functions&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    const connectWallet =() =&amp;gt; {
        return connector.connect();
    };
    const killSession =() =&amp;gt; {
        setValue({wallet:0});

        return connector.killSession();
    };
    const sendButtonHandler = () =&amp;gt; {
        console.log('Pressed');
        console.log('Value is: ',value)
        if (value.amount &amp;lt;5 &amp;amp;&amp;amp; value.amount &amp;amp;&amp;amp; value.receiver &amp;amp;&amp;amp; value.wallet &amp;amp;&amp;amp; connector.connected &amp;amp;&amp;amp; ownerAddress) {
            Alert.alert('Warning!!','Are you sure you want to send this?',[
                {
                    text:'No',
                    onPress:() =&amp;gt; {
                        console.log('No Pressed');
                    },
                    style:'cancel'
                },
                {
                    text:'Yes',
                    onPress:() =&amp;gt; {
                        console.log('Yes Pressed');

                    },
                    style:'destructive'
                }
            ])
            return;
        }
        Alert.alert('Error','Please fill all the fields correctly');
    };
    function connectButtonHandler(){
        console.log('Pressed',value.wallet)
        if(value.wallet===2){
            connectWallet();
        }
    }
    useEffect(() =&amp;gt; {
        if(connector.connected){
            setOwnerAddress(connector.accounts[0]);
        }
    }, [connector.connected]);
    function Button({ onPress, label }) {
        return (
            &amp;lt;TouchableOpacity onPress={onPress} style={styles.button}&amp;gt;
                &amp;lt;Text style={styles.text}&amp;gt;{label}&amp;lt;/Text&amp;gt;
            &amp;lt;/TouchableOpacity&amp;gt;
        );
    }
    useEffect(() =&amp;gt; {
        connectButtonHandler();
    }, [value.wallet]);


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now let we will be binding this to their respective buttons. The final code in the &lt;strong&gt;&lt;em&gt;&lt;code&gt;&lt;br&gt;
&lt;br&gt;
Mainpage.jsx&lt;/code&gt;&lt;/em&gt;&lt;/strong&gt; is like this&lt;br&gt;
&lt;a href="https://github.com/OliverMengich/CryptoApp/blob/main/screens/MainPage.js" rel="noopener noreferrer"&gt;Final Code&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>blockchain</category>
      <category>web3</category>
      <category>trustwallet</category>
    </item>
    <item>
      <title>React Router v6</title>
      <dc:creator>Oliver Kem</dc:creator>
      <pubDate>Fri, 16 Jun 2023 13:55:24 +0000</pubDate>
      <link>https://dev.to/olivermengich/react-router-v6-2nc7</link>
      <guid>https://dev.to/olivermengich/react-router-v6-2nc7</guid>
      <description>&lt;p&gt;Hello Everyone, React router v6 is out. I have been tinkering with it for a while and I love it. With everything updated and some new hooks to use with your application, I have decided to write this article to share my knowledge on it. Let's begin&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Javascript/Typescript&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, let us begin. We will start by creating our React Application using &lt;a href="https://vitejs.dev"&gt;vite&lt;/a&gt;. I will be using &lt;code&gt;pnpm&lt;/code&gt; but feel free to use &lt;code&gt;yarn&lt;/code&gt; or &lt;code&gt;npm&lt;/code&gt;.&lt;br&gt;
Go to your terminal and run the following commands&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pnpm create vite@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the prompts and select Typescript. Install the dependencies and start the app&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DqQGcyRG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kjl8l3uxis2auuv4ywy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DqQGcyRG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kjl8l3uxis2auuv4ywy.png" alt="Installation Screenshot" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let us start by installing the React router library &lt;a href="https://reactrouter.com/en/main"&gt;React Router&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pnpm add react-router-dom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us create a page. Create a folder called &lt;code&gt;pages&lt;/code&gt; in &lt;code&gt;scr&lt;/code&gt; and called it &lt;code&gt;HomePage.tsx&lt;/code&gt;. Then paste the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function HomePage() {
    return (
        &amp;lt;div&amp;gt;
            &amp;lt;h1&amp;gt;Home Page&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
    );
}

export default HomePage;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, on our App.tsx&lt;br&gt;
We need to write the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import './App.css'
import { createBrowserRouter,RouterProvider} from "react-router-dom";
import HomePage from "./pages/HomePage";
function App() {
  const router = createBrowserRouter([
    { 
      path: "/",
      element: &amp;lt;HomePage/&amp;gt;
    },
  ]);
  return (
    &amp;lt;RouterProvider router={router}/&amp;gt;
  )
}

export default App
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when someone visits our &lt;code&gt;http://localhost:5173/&lt;/code&gt; they will be greeted with this page.&lt;/p&gt;

&lt;p&gt;Now, in your application. You May have an overall layout comprising a design that your want other pages to wrap around this. Let me show you how we can do it.&lt;br&gt;
Create a folder called &lt;code&gt;components&lt;/code&gt; and add a file called &lt;code&gt;layouts.component.tsx&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { OutLet } from `react-router-dom`;
function LayoutsComponent() {
    return (
        &amp;lt;div&amp;gt;
            &amp;lt;h1&amp;gt;This is the overall layout&amp;lt;/h1&amp;gt;
            &amp;lt;Outlet/&amp;gt;
        &amp;lt;/div&amp;gt;
    );
}

export default LayoutsComponent;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us create two pages &lt;code&gt;UsersPage.tsx&lt;/code&gt; and &lt;code&gt;ProductsPage.tsx&lt;/code&gt;. Now add some dummy data and we import them in our &lt;code&gt;App.tsx&lt;/code&gt;&lt;br&gt;
Now with this, we need to wrap our app with this layout.&lt;br&gt;
In our &lt;code&gt;App.tsx&lt;/code&gt; page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import './App.css'
import { createBrowserRouter,RouterProvider} from "react-router-dom";
import HomePage from "./pages/HomePage";
import LayoutsComponent from './components/layouts.component';
import UsersPage from './pages/UsersPage';
import ProductsPage from './pages/ProductsPage';
function App() {
    const router = createBrowserRouter([
        { 
            path: "/",
            element: &amp;lt;HomePage/&amp;gt;,
        },
        {
            element: &amp;lt;LayoutsComponent/&amp;gt;,
            children: [
                {
                path: "/users",
                element: &amp;lt;UsersPage/&amp;gt;,
                },
                {
                path: "/products",
                element: &amp;lt;ProductsPage/&amp;gt;,
                },
            ],
        }
    ]);
    return (
        &amp;lt;RouterProvider router={router}/&amp;gt;
    )
}

export default App

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;From above, we have just passed the &lt;code&gt;&amp;lt;UsersPage/&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;ProductsPage/&amp;gt;&lt;/code&gt; as children to the &lt;code&gt;&amp;lt;LayoutsComponent/&amp;gt;&lt;/code&gt; page, now they will wrap inside.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, in the Layouts component, you might want to pass data to every child component that might be wrapping inside it. This might come in handy, for example when you are designing for responsive view and you want to pass data to its children to respond a certain way when the layout changes. To do this we will us a special hook called &lt;code&gt;useOutletContext()&lt;/code&gt; but before we do this, in the &lt;code&gt;layout.component.tsx&lt;/code&gt; let us pass some data to the children.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEffect, useState } from "react";
import { Outlet } from "react-router-dom";
function LayoutsComponent() {
    const [data,setData] = useState([]);
    useEffect(() =&amp;gt; {
        fetch('https://jsonplaceholder.typicode.com/users')
        .then(response =&amp;gt; response.json())
        .then(json =&amp;gt; setData(json))
    },[])
    return (
        &amp;lt;div&amp;gt;
            &amp;lt;h1&amp;gt;This is the overall layout&amp;lt;/h1&amp;gt;
            &amp;lt;Outlet context={[data]} /&amp;gt;
        &amp;lt;/div&amp;gt;
    );
}

export default LayoutsComponent;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From our example, we have just updated our application import and now the data will be used my the children here.&lt;br&gt;
Now to consume the data in our children(UsersPage):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useOutletContext } from "react-router-dom";
function UsersPage() {
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    const [ data  ]= useOutletContext&amp;lt;[string[]]&amp;gt;();
    return (
        &amp;lt;div&amp;gt;
            &amp;lt;h1&amp;gt;Users Page&amp;lt;/h1&amp;gt;
            &amp;lt;ul&amp;gt;
                {data.map((item,index) =&amp;gt; (
                    &amp;lt;li key={index}&amp;gt;{item}&amp;lt;/li&amp;gt;
                ))}
            &amp;lt;/ul&amp;gt;
        &amp;lt;/div&amp;gt;
    );
}

export default UsersPage;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let us spice things up. You may want to introduce a loader, such that before we view a user information, before we view navigate to the user's profile page. To do this we write the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    path: "/users",
        element: &amp;lt;UsersPage/&amp;gt;,
    children: [
            {
                 path: ":id",
                 element: &amp;lt;UserProfile/&amp;gt;,
                 loader: async ({ params }) =&amp;gt; {
                const response = await fetch(`https://jsonplaceholder.typicode.com/users/${params.id}`);
                const data = await response.json();
                return data;
                  }
            },
       ],
},
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From this, you can choose to display the user data information&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useLoaderData } from "react-router-dom";
function UserProfile() {
    const data= useLoaderData();

    return (
        &amp;lt;div&amp;gt;
            &amp;lt;h1&amp;gt;User Profile&amp;lt;/h1&amp;gt;
            &amp;lt;p&amp;gt;{data}&amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
    );
}

export default UserProfile;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feel free to check the original documentation &lt;a href="https://reactrouter.com/en/main/start/overview"&gt;Docs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactrouter</category>
      <category>typescript</category>
      <category>vite</category>
    </item>
    <item>
      <title>File download in React Native and Expo</title>
      <dc:creator>Oliver Kem</dc:creator>
      <pubDate>Sat, 20 May 2023 12:12:01 +0000</pubDate>
      <link>https://dev.to/olivermengich/file-download-in-react-native-and-expo-gk8</link>
      <guid>https://dev.to/olivermengich/file-download-in-react-native-and-expo-gk8</guid>
      <description>&lt;p&gt;Hello, today I am going to show us how you can can save files in React Native. If you are fetching a file from the backend server through an API endpoint, you will need to find a way to save the files to your phone. With this, you will have to figure out how you can handle permissions to access the files. I want to show you how you can handle permissions in React Native. I am using Expo.&lt;br&gt;
After trying &lt;code&gt;rn-fetch-blob&lt;/code&gt; and other libraries, I found out that they are not compatible with expo. (Only React Native CLI)&lt;/p&gt;

&lt;p&gt;We have to consider about file system access and permissions.&lt;br&gt;
After setting up a React Native Application and Adding a button. Let as get started, go to your terminal then type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add axios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I will be using axios to fetch the resource. Since expo is so strict with installing some files, I will be installing the libraries using expo. We are going to install &lt;code&gt;expo-file-system&lt;/code&gt; library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx expo install expo-file-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then go to your file, and import the library&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as FileSystem from 'expo-file-system';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we write a function to fetch the resource.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function fetchReportForm(fileType: string){

        axios.post(`https://resource.url`).then(async(res)=&amp;gt;{
            const pdfData = res.data;
        })
        .catch((err)=&amp;gt;{
            Alert.alert('Error','Error Downloading File!!')
        })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we write a function to fetch the resource that helps us with file permissions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const requestFileWritePermission =async () =&amp;gt; {
        const permissions = await FileSystem.StorageAccessFramework.requestDirectoryPermissionsAsync();
        console.log(permissions.granted);
        if (!permissions.granted) {
                     Alert.alert('Error','File Permissions Denied')
            return {
                access: false,
                directoryUri: null
            };
        }
        return {
            access:true,
            directoryUri: permissions.directoryUri
        };
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, the user will be prompted with a request for directory to download the file, it then returns an object with the directory uri to save the file to. Now, we will be using thi directory uri to save the file.&lt;br&gt;
Now let's write a function to help us save the file to our file system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as FileSystem from 'expo-file-system';
const saveReportFile = async (pdfData: any,directoryUri: string)=&amp;gt;{
        try {
            await FileSystem.StorageAccessFramework.createFileAsync(directoryUri, 'My_file', 'application/pdf')
            .then(async(uri) =&amp;gt; {
                await FileSystem.writeAsStringAsync(uri, pdfData, { encoding: FileSystem.EncodingType.Base64 });
            }).then(res=&amp;gt;{
                console.log(res)
                Alert.alert('Success', `File Saved`)
            })
            .catch((e) =&amp;gt; {
                console.log(e);
            });
        } catch (error) {
            Alert.alert('Error',`Could not Download file ${error.message}`);
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function takes 2 inputs pdfData and the directoryUri to save the file. I passed the &lt;code&gt;My_file&lt;/code&gt; as the file name.&lt;br&gt;
Now, let us bundle up the whole code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const requestFileWritePermission =async () =&amp;gt; {
        const permissions = await FileSystem.StorageAccessFramework.requestDirectoryPermissionsAsync();
        console.log(permissions.granted);
        if (!permissions.granted) {
            console.log('File write Permissions Denied!!')
            return {
                access: false,
                directoryUri: null
            };
        }
        return {
            access:true,
            directoryUri: permissions.directoryUri
        };
}
const saveReportFile = async (pdfData: any,directoryUri: string)=&amp;gt;{
        try {
            await FileSystem.StorageAccessFramework.createFileAsync(directoryUri,'My_file', 'application/pdf')
            .then(async(uri) =&amp;gt; {
                await FileSystem.writeAsStringAsync(uri, pdfData, { encoding: FileSystem.EncodingType.Base64 });
            }).then(res=&amp;gt;{
                console.log(res)
                Alert.alert('Success', `File Saved`)
            })
            .catch((e) =&amp;gt; {
                console.log(e);
            });
        } catch (error) {
            Alert.alert('Error',`Could not Download file ${error.message}`);
        }
    }
    async function fetchReportForm(fileType: string){
        console.log('Attempting to Download file: ', fileType,'Report is',reportToDownload.stream);
        axios.post(``).then(async(res)=&amp;gt;{
            const pdfData = res.data;
            const hasPermissions = await requestFileWritePermission();
            if (hasPermissions.access) {
                saveReportFile(pdfData, hasPermissions.directoryUri)
            }
        })
        .catch((err)=&amp;gt;{
            console.log(err)
            Alert.alert('Error','Error Downloading File!!')
        })
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, you are done.&lt;br&gt;
Gracias, see you soon.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>mobile</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Integrating Credentials Provider with NextAuthJS and MongoDB with Typescript - Part 2</title>
      <dc:creator>Oliver Kem</dc:creator>
      <pubDate>Thu, 27 Apr 2023 19:07:41 +0000</pubDate>
      <link>https://dev.to/olivermengich/integrating-credentials-provider-with-nextauthjs-and-mongodb-with-typescript-part-2-52pb</link>
      <guid>https://dev.to/olivermengich/integrating-credentials-provider-with-nextauthjs-and-mongodb-with-typescript-part-2-52pb</guid>
      <description>&lt;p&gt;Now, we work on the client side, in the client side, we will be handling how we can protect routes and how we can interact with the logged in user through an active session. With that, let's start.&lt;br&gt;
From part 1 &lt;a href="https://dev.to/olivermengich/integrating-credentials-provider-with-nextauthjs-and-mongodb-with-typescript-4a25"&gt;Part 1&lt;/a&gt; we were done with returning the logged in user information (id, name and email) We will now use this in the frontend&lt;/p&gt;

&lt;p&gt;Let's handle with the sign up functionality. From our frontend, sign up page let's start&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { SyntheticEvent, useReducer } from 'react';
import { signIn } from 'next-auth/react';
function FormComponent() {
    const handleFormSubmit = async (e: SyntheticEvent)=&amp;gt;{
        e.preventDefault();
        const { password, ...others } = state;
        if (password !==others['confirm-password']) {
            dispatch({name:'response',value:{code:401,message:"Passwords don't match!!"}})
        }
        type sentResponse = Omit&amp;lt;FormComponents,'confirm-password'|'response'| 'passwordType'&amp;gt;
        const sendingResp: sentResponse = {
            name: state.name,
            email: state.email,
            password: state.password,

        }
        const res = await fetch('/api/auth/sign-up',{
            method: 'POST',
            headers:{
                'Content-Type':'application/json'
            },
            body: JSON.stringify({...sendingResp})
        })
        const data = await res.json();
        console.log(data.message,res.status);
        if (res.status===(200| 201)) {
            //sign in the user
            const status = await signIn('credentials', {
                redirect: false,
                email: state.email,
                password: state.password
            })
            console.log(status);
        }

        dispatch({name:'response',value:{code:res.status,message:data.message}})
    }
    type FormComponents={
        name: string
        email: string
        password: string
        response: {
            code: number,
            message: string
        }
    }
    const formVals: FormComponents={
        name: '',
        email: '',
        password: '',
        'confirm-password': '',
        response: {
            code: 0,
            message: ''
        },
    }
    function signInReducer(prev: FormComponents,next: {name :string,value: string | {code:number,message:string} | boolean}) {
        return {
            ...prev,
            [next.name]: next.value
        }
    }
    const [state,dispatch] = useReducer(signInReducergit,formVals)
    function handleOnChange(e: React.FormEvent&amp;lt;HTMLInputElement&amp;gt; | React.FormEvent&amp;lt;HTMLSelectElement&amp;gt;){
        if (e.target instanceof HTMLSelectElement) {
            dispatch({name: e.target.name,value: e.target.value})
           return;
        }
        const {name,value} = e.target as HTMLTextAreaElement
        dispatch({name: name ,value: value})
    }

    return (
        &amp;lt;&amp;gt;

            &amp;lt;div className={styles.form_container}&amp;gt;
                &amp;lt;form className={styles.form} onSubmit={handleFormSubmit}&amp;gt;
                    &amp;lt;p style={{fontWeight: 'bold', fontSize: '20px'}}&amp;gt;Create an Account Today!!&amp;lt;/p&amp;gt;
                    {
                        state.response.message?(
                            &amp;lt;p  className={state.response.code===201? styles.success_message:styles.failure_message}&amp;gt;{state.response.message}&amp;lt;/p&amp;gt;
                        ):''
                    }
                    &amp;lt;div className={styles.form_element}&amp;gt;
                        &amp;lt;label&amp;gt;Name&amp;lt;/label&amp;gt;
                        &amp;lt;input name='name' value={state.name} required type="text" onChange={handleOnChange} /&amp;gt;
                    &amp;lt;/div&amp;gt;
                    &amp;lt;div className={styles.form_element}&amp;gt;
                        &amp;lt;label&amp;gt;Email&amp;lt;/label&amp;gt;
                        &amp;lt;input name='email' value={state.email} required type="email" onChange={handleOnChange}/&amp;gt;
                    &amp;lt;/div&amp;gt;

                    &amp;lt;div className={styles.form_element}&amp;gt;
                        &amp;lt;label &amp;gt;Password&amp;lt;/label&amp;gt;
                        &amp;lt;input name='password' value={state.password} required type="password" onChange={handleOnChange} /&amp;gt;
                    &amp;lt;/div&amp;gt;
                    &amp;lt;div className={styles.form_element}&amp;gt;
                        &amp;lt;label&amp;gt;Confirm Password&amp;lt;/label&amp;gt;
                        &amp;lt;input name='confirm-password' value={state['confirm-password']} required type="password" onChange={handleOnChange} /&amp;gt;
                    &amp;lt;/div&amp;gt;

                    &amp;lt;input required type="submit" value="SIGN UP" /&amp;gt;
                &amp;lt;/form&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/&amp;gt;
    );
}

export default FormComponent;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have just handled the sign up component. We are using &lt;code&gt;useReducer&lt;/code&gt; in react where we store user state (user information) from the state, after that, we send a post request to the backend router &lt;code&gt;/api/auth/sign-up&lt;/code&gt; page, the file will now be executed. &lt;br&gt;
After a positive response from the server &lt;em&gt;i.e&lt;/em&gt; the response is of type &lt;strong&gt;200 status code&lt;/strong&gt;, we now proceed to sign in the user. We have just imported the &lt;code&gt;signIn&lt;/code&gt; function from the &lt;code&gt;next-auth&lt;/code&gt; library. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When we sign in, next-auth will now be responsible with storing the user session, this is amazing because we don't have to use a state management tool to store the user information. &lt;code&gt;next-auth&lt;/code&gt; handles that for us  &lt;strong&gt;THIS IS AMAZING&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now let's proceed with the login functionality.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function handleSignIn(e: SyntheticEvent){
        e.preventDefault();
        const status = await signIn('credentials',{
            redirect: false,
            email: state.email,
            password: state.password
        })
        console.log(status)
 }
&amp;lt;form onSubmit={handleSignIn}&amp;gt;
                    &amp;lt;p &amp;gt;Already have an Account? &amp;lt;/p&amp;gt;
                    &amp;lt;div &amp;gt;
                        &amp;lt;label&amp;gt;Email&amp;lt;/label&amp;gt;
                        &amp;lt;input name='email' value={state.email} required type="email" onChange={handleOnChange}/&amp;gt;
                    &amp;lt;/div&amp;gt;
                    &amp;lt;div className={styles.form_element}&amp;gt;
                        &amp;lt;label&amp;gt;Password&amp;lt;/label&amp;gt;
                        &amp;lt;input name='password' value={state.password} required type={state.passwordType?'text':'password'} onChange={handleOnChange} /&amp;gt;
                        &amp;lt;p onClick={()=&amp;gt;dispatch({name:'passwordType', value: !state.passwordType})}  style={{cursor:'pointer',display:'inline-block'}}&amp;gt;show&amp;lt;/p&amp;gt;
                    &amp;lt;/div&amp;gt;
                    &amp;lt;input onClick={handleSignIn} type="submit" value="SIGN IN" /&amp;gt;
                    &amp;lt;input style={{color: 'white', background:'blue'}} required type="submit" value="SIGN IN WITH GOOGLE" /&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This session of code is self explanatory, upon sign in, the &lt;code&gt;[...nextauth.ts]&lt;/code&gt; file will be executed, this will now be responsible for signing in our user. Amazing&lt;/p&gt;

&lt;p&gt;Now, let's handle how we can protect some route. In our Navigation, we would wish to protect a link to a route i.e user dashboard&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Link from "next/link";
import React from "react";
import Image from "next/image";
import { useSession } from "next-auth/react";
import { signOut } from "next-auth/react";
function NavComponent() {
    const {data: session} = useSession();
    return(
        &amp;lt;header&amp;gt;
            &amp;lt;h1&amp;gt;My App&amp;lt;/h1&amp;gt;
            &amp;lt;nav &amp;gt;
                &amp;lt;ul &amp;gt;
                    &amp;lt;li&amp;gt;
                        &amp;lt;Link href='/'&amp;gt;Home&amp;lt;/Link&amp;gt;
                    &amp;lt;/li&amp;gt;

                    &amp;lt;li&amp;gt;
                        &amp;lt;Link href='/partners'&amp;gt;Partners&amp;lt;/Link&amp;gt;
                    &amp;lt;/li&amp;gt;
                    {
                        session &amp;amp;&amp;amp; (
                            &amp;lt;li&amp;gt;
                                &amp;lt;Link href='/my-dashboard'&amp;gt;My Dashboard&amp;lt;/Link&amp;gt;
                            &amp;lt;/li&amp;gt;
                        )
                    }
                    {
                        session &amp;amp;&amp;amp; (
                            &amp;lt;li&amp;gt;
                                &amp;lt;Link href='/doctor-dashboard'&amp;gt;My Dashboard&amp;lt;/Link&amp;gt;
                            &amp;lt;/li&amp;gt;
                        )
                    }
                    &amp;lt;li&amp;gt;
                        &amp;lt;Link href='/contact'&amp;gt;Contact Us&amp;lt;/Link&amp;gt;
                    &amp;lt;/li&amp;gt;
                &amp;lt;/ul&amp;gt;
                &amp;lt;div &amp;gt;
                    {
                        session &amp;amp;&amp;amp; (
                            &amp;lt;div &amp;gt;
                                &amp;lt;Image src='/images/cart.webp' alt="image" /&amp;gt;
                                &amp;lt;div&amp;gt;
                                    &amp;lt;h4&amp;gt;{session.user?.name}&amp;lt;/h4&amp;gt;
                                    &amp;lt;p&amp;gt;{session.user?.id}&amp;lt;/p&amp;gt;
                                &amp;lt;/div&amp;gt;
                            &amp;lt;/div&amp;gt;
                        )
                    }
                    {
                        !session &amp;amp;&amp;amp; (
                            &amp;lt;button &amp;gt;
                                &amp;lt;Link href='/auth'&amp;gt;Login/Register&amp;lt;/Link&amp;gt;
                            &amp;lt;/button&amp;gt;
                        )
                    }
                    {
                        session &amp;amp;&amp;amp; (
                            &amp;lt;button onClick={()=&amp;gt;signOut()} &amp;gt;
                                Logout
                            &amp;lt;/button&amp;gt;
                        )
                    }
                    {
                        session &amp;amp;&amp;amp; (
                            &amp;lt;button&amp;gt;Book Appointment&amp;lt;/button&amp;gt;
                        )
                    }
                &amp;lt;/div&amp;gt;
            &amp;lt;/nav&amp;gt;
        &amp;lt;/header&amp;gt;
    )
}
export default NavComponent;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this navigation component, we have protected the user Dashboard. We also want to display a user image and name when there's an active session. &lt;code&gt;next-auth&lt;/code&gt; also provides a sign out library function where we can log out our user easily.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Now for our final part, let's protect a user page. It's always good to protect a page containing user information page&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import Link from 'next/link';
import { getSession } from 'next-auth/react';
function DoctorDashboard() {
    const [toogle, setToogle] = React.useState(false);
    const handleClick = () =&amp;gt; {
        setToogle(!toogle);
    }
    return (
        &amp;lt;&amp;gt;
            &amp;lt;div style={{margin: '20px'}}&amp;gt;
               &amp;lt;h1&amp;gt; User information dashboard&amp;lt;/h1&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/&amp;gt;
    );
}
export async function getServerSideProps(context: GetServerSidePropsContext){
        const session= await getSession(context);
        if (!session) {
            return{
                redirect:{
                    destination:'/auth',
                    permanent: false
                }
            }
        }
        //Do your logic e.g fetching a user information from the // backend to retrieve information
        return{
            props:{
                //data
            }
        }
  }

export default DoctorDashboard;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;From this section of code, when a user navigates to this route and he/she isn't logged in (no active session), they are being redirected back to the &lt;code&gt;/auth&lt;/code&gt; page, amazing. This is just amazing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And with this we are done with our two sections we are done.&lt;br&gt;
For more information, find everything from the official documentation. &lt;a href="https://next-auth.js.org/"&gt;Next Auth Docs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextauth</category>
      <category>typescript</category>
      <category>nextjs</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>Implementing Login with Metamask, send Ether, user registration using React, NodeJS, Sequelize and GraphQL</title>
      <dc:creator>Oliver Kem</dc:creator>
      <pubDate>Mon, 17 Apr 2023 12:22:41 +0000</pubDate>
      <link>https://dev.to/olivermengich/implementing-login-with-metamask-send-ether-user-registration-using-react-nodejs-sequelize-and-graphql-35k7</link>
      <guid>https://dev.to/olivermengich/implementing-login-with-metamask-send-ether-user-registration-using-react-nodejs-sequelize-and-graphql-35k7</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.tourl"&gt;&lt;/a&gt;## &lt;u&gt;In&lt;/u&gt; this Project we are going to learn how you can implement a login functionality using React on frontend NodeJS backend with GraphQL and stores data on an SQL database. When creating DAPPs there’s always a need to implement functionality where users can login there metamask account to your applications once they are registered.&lt;/p&gt;

&lt;p&gt;In this article, we will be generating JWT tokens to allow users to access protected routes in NodeJS.&lt;/p&gt;

&lt;p&gt;Let’s look at the authentication flow in the image below.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A720%2Fformat%3Awebp%2F1%2AOGjgv9BT4w71MVYdi02MTg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A720%2Fformat%3Awebp%2F1%2AOGjgv9BT4w71MVYdi02MTg.png" alt="Auth flow"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;NodeJS&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Metamask&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, let’s get started. Go to your terminal, create a new folder name it any name you like. I’ll call it web3-login.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pnpm create vite@latest 
code web3-login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now in this folder, let’s create another directory here, call it backend, and install a couple of dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir backend
cd backend
npm init -y
npm i bcryptjs web3 ethereumjs-util uuid express sequelize jsonwebtoken
npm i express-graphql graphql sqlite3
npm i -D nodemon
mkdir graphql
mkdir database models 
cd graphql &amp;amp;&amp;amp; mkdir resolvers &amp;amp;&amp;amp; mkdir schema
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, on your frontend run the following in terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i @metamask/detect-provider web3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your folders should look like this:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A622%2Fformat%3Awebp%2F1%2AZao4zK_eoM7EgpnHqLhruw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A622%2Fformat%3Awebp%2F1%2AZao4zK_eoM7EgpnHqLhruw.png" alt="folder_vieq"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, in your backend directory, make a new file. call it index.js. type in the following lines of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const {graphqlHTTP} = require('express-graphql');
// we will make this folder. Keep following
const graphqlSchema = require('./graphql/schema/schema.graphql');
const graphqlResolver = require('./graphql/resolvers/resolvers.graphql.js');
const sequelize = require('./database/db');

const app = express();
app.use(express.json());
// you can also use the CORS library of nodejs
app.use((req, res, next)=&amp;gt;{
    res.setHeader("Access-Control-Allow-Origin","*");
    res.setHeader("Access-Control-Allow-Methods","POST,GET,OPTIONS");
    res.setHeader("Access-Control-Allow-Headers", 'Content-Type, Authorization');
    if(req.method ==="OPTIONS"){
        return res.sendStatus(200);
    }
    next();
});
// creates a graphql server
app.use('/users',graphqlHTTP({
    schema: graphqlSchema,
    rootValue: graphqlResolver,
    graphiql: true
}))
sequelize
.sync()
.then(res=&amp;gt;{
    // only connects to app when
    app.listen(4000,()=&amp;gt;{
        console.log("Backend Server is running!!");
    })
})
.catch(err=&amp;gt;console.error);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, go to your database folder. create a new file. call it db.js. copy and paste this line of code. Also create a new file with the .sqlite extension. e.g. db.sqlite&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const sequelize = require('../database/db');

const { DataTypes } = require('sequelize');
const User = sequelize.define('Users', {
    id: {
        type: DataTypes.UUIDV1,
        allowNull: false,
        primaryKey: true
    },
    email: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true
    },
    password: {
        type: DataTypes.STRING(64),
        allowNull: false
    },
    address: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true
    },
    nonce: {
        type: DataTypes.INTEGER,
        allowNull: false,
        unique: true
    },
},{
    timestamps: true
}
);
module.exports = User;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ll use the nonce parameter for cryptographic communication. We store the address of user for verification.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now, go to your graphql/schema folder&lt;/li&gt;
&lt;li&gt;Create a new file. call it graphql.schema.js&lt;/li&gt;
&lt;li&gt;Paste in the following lines of code
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const {buildSchema} = require('graphql');
//we build the schema here.
module.exports = buildSchema(`
    type User{
        id: ID!
        email: String!
        password: String
        address: String!
        nonce: Int!
    }
    input UserInput{
        email: String!
        password: String!
        address: String!
    }
    type AuthData{
        userId: ID!
        token: String!
        tokenExpiration: Int!
    }
    type Token{
        nonce: Int
    }
    type jwtToken{
        token: String,
        message: String
    }
    type RootQuery {
        loginMetamask(address: String!): Token!
        login(email: String!, password: String!): AuthData!
        signatureVerify(address: String!,signature: String!): jwtToken!
        users: [User!]
    }
    type RootMutation {
        register(userInput: UserInput): User!
    }
    schema {
        query: RootQuery
        mutation: RootMutation
    }
`);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Go to graphql/resolvers folder&lt;/li&gt;
&lt;li&gt;Create a new file. call it graphql.resolvers.js&lt;/li&gt;
&lt;li&gt;Let's start with user registration
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const User = require('../../models/user.model.js');
module.exports = {
  //from our schema, we pass in the user email, password and address,
  // a nonce is generated
  register: (args) =&amp;gt; {
      return User.create({
          id: uuid.v1(),
          ...args.userInput,
          nonce: Math.floor(Math.random() * 1000000)
      }).then(res=&amp;gt;{
          console.log(res);
          return res
      }).catch(err=&amp;gt;{
          console.log(err);
      })  
    },
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we go on the frontend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return(
        &amp;lt;div className="login_metamask"&amp;gt;
            &amp;lt;h1&amp;gt;Metamask&amp;lt;/h1&amp;gt;
            &amp;lt;div className="success"&amp;gt;
                &amp;lt;h3&amp;gt;Succcessfull Transaction&amp;lt;/h3&amp;gt;
                &amp;lt;div className="animation-slider"&amp;gt;&amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;section className="metamask__action"&amp;gt;
                &amp;lt;button onClick={Enable_metamask} className="enable_metamask"&amp;gt;
                    &amp;lt;img src={require("../images/metamask.png")} alt="metamaskimage" /&amp;gt;
                    &amp;lt;h2&amp;gt;Enable Metamask&amp;lt;/h2&amp;gt;
                &amp;lt;/button&amp;gt;
                &amp;lt;button onClick={send_metamask} className="enable_metamask"&amp;gt;
                    &amp;lt;img src={require("../images/metamask.png")} alt="metamaskimage" /&amp;gt;
                    &amp;lt;h2&amp;gt;Send Ether&amp;lt;/h2&amp;gt;
                &amp;lt;/button&amp;gt;
                &amp;lt;button onClick={Login_metamask} className="enable_metamask"&amp;gt;
                    &amp;lt;img src={require("../images/metamask.png")} alt="metamaskimage" /&amp;gt;
                    &amp;lt;h2&amp;gt;Login with Metamask&amp;lt;/h2&amp;gt;
                &amp;lt;/button&amp;gt;
                &amp;lt;button onClick={Logout_metamask} className="enable_metamask"&amp;gt;
                    &amp;lt;img src={require("../images/metamask.png")} alt="metamaskimage" /&amp;gt;
                    &amp;lt;h2&amp;gt;LOGOUT&amp;lt;/h2&amp;gt;
                &amp;lt;/button&amp;gt;
            &amp;lt;/section&amp;gt;
        &amp;lt;/div&amp;gt;
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A1400%2Fformat%3Awebp%2F1%2AWDhvFTB9mqosjryWAYtG8A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A1400%2Fformat%3Awebp%2F1%2AWDhvFTB9mqosjryWAYtG8A.png" alt="Image of metamsk"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we need to enable meta mask. When you click the “ENABLE METAMASK” button, the code will run and pop up window will open. Key in your password.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Web3 from "web3";
import detectEthereumProvider from "@metamask/detect-provider";
async function Enable_metamask(){
    const provider = await detectEthereumProvider();
    if (provider) {
        window.web3 = new Web3(provider);
        web3 = window.web3;
        ethereum = window.ethereum;
        const chainId = await ethereum.request({ method: 'eth_chainId' });
        const accounts  = await ethereum.request({ method: 'eth_requestAccounts' });
        account = accounts[0];
        console.log(chainId, accounts);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s implement the login with Metamask functionality:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function Login_metamask(){
        //1. First we query for the user nonce in the backend passing in the user account address
        let requestBody={
            query: `
                query {
                    loginMetamask(address: "${account}"){
                        nonce
                    }
                }
            `
        }
        const handleSignMessage = (nonce, publicAddress) =&amp;gt; {
            return new Promise((resolve, reject) =&amp;gt;
                web3.eth.personal.sign(
                    web3.utils.fromUtf8(`Nonce: ${nonce}`),
                    publicAddress,
                    (err, signature) =&amp;gt; {
                        if (err) return reject(err);
                        return resolve({ publicAddress, signature });
                    }
                )
            );
        }
        //2. if metamask is enabled we send in the request
        if(web3 &amp;amp;&amp;amp; ethereum &amp;amp;&amp;amp; account){
            fetch('http://localhost:4000/users', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(requestBody),
            })
            .then(res=&amp;gt;{
                if(res.status !== 200 &amp;amp;&amp;amp; res.status !==201){
                    //3. if we get an error, respond error
                    throw new Error("Failed");
                }
                return res.json();
            })
            .then(data =&amp;gt; {
                console.log(data);
                  //4.  we log retrieve the nonce
                const nonce = data.data.loginMetamask.nonce;
                console.log(nonce);
                if(nonce != null){
                    //5. we then generate a signed message. and send it to the backend
                    return handleSignMessage(nonce,account)
                    .then((signedMessage)=&amp;gt;{
                        console.log(signedMessage.signature)
                        requestBody = {
                            query: `
                                query {
                                    signatureVerify(address: "${account}",signature: "${signedMessage.signature}"){
                                        token
                                        message
                                    }
                                }
                            `
                        }
                        fetch('http://localhost:4000/users', {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json',
                            },
                            body: JSON.stringify(requestBody),
                        })
                        .then(response =&amp;gt;{
                            if(response.status !== 200 &amp;amp;&amp;amp; response.status !==201){
                                throw new Error('Failed');
                            }
                            return response.json();
                        })
                        .then(data =&amp;gt; {
                            console.log(data);
                        })
                        .catch(err=&amp;gt;console.error); 
                    })
                }else{
                    //Redirect the user to registration site.
                    console.log('Please Register at our site. ')
                }
            })
            .catch((error) =&amp;gt; {
                console.error('Error encountered:', error);
            });
        }else{
            await Enable_metamask();
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, on our backend we receive this request and process it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const User = require('../../models/user.model.js');
function VerifySignature(signature,nonce) {
    const msg = `Nonce: ${nonce}`;
    //convert the message to hex
    const msgHex = ethUtil.bufferToHex(Buffer.from(msg));
    //if signature is valid
    const msgBuffer = ethUtil.toBuffer(msgHex);
    const msgHash = ethUtil.hashPersonalMessage(msgBuffer);
    const signatureBuffer = ethUtil.toBuffer(signature);
    const signatureParams = ethUtil.fromRpcSig(signatureBuffer);
    const publicKey = ethUtil.ecrecover(
        msgHash,
        signatureParams.v,
        signatureParams.r,
        signatureParams.s
    );
    const addressBuffer = ethUtil.publicToAddress(publicKey);
    const secondaddress = ethUtil.bufferToHex(addressBuffer);
    return secondaddress;
}
module.exports = {
  //from our schema, we pass in the user email, password and address,
  // a nonce is generated
    register: (args) =&amp;gt; {
        return User.create({
            id: uuid.v1(),
            ...args.userInput,
            nonce: Math.floor(Math.random() * 1000000)
        }).then(res=&amp;gt;{
            console.log(res);
            return res
        }).catch(err=&amp;gt;{
            console.log(err);
        })  
    },
    loginMetamask: function({address}){
          return User.findOne({address})
          .then(user=&amp;gt;{
              if(!user){
                  // if user doesn't exit return null
                  return{
                      nonce: null
                  }
              }
              return {
                //else return the nonce of user
                  nonce: user.dataValues.nonce
              }
          })
          .catch(err=&amp;gt;{
              throw err;
          })
    },
    signatureVerify:async function({address, signature}){
            const user =await User.findOne({address});
            if(!user){
                return{
                    token: null,
                    message: 'User not Found. Sign In again'
                }
            }
            // then verify the signature sent by the user i
            let secondaddress = VerifySignature(signature,user.nonce)
            if(address.toLowerCase() === secondaddress.toLowerCase()){
                //change the user nonce
                user.nonce = Math.floor(Math.random() * 1000000);
                await user.save()
                const token = await jwt.sign({address: user.address,email: user.email},'HelloMySecretKey',{expiresIn: '1h'});
                return{
                    token: token,
                    message: 'User not Found. Sign In again'
                }
            }else {
                return{
                    token: null,
                    message: 'User not Found. Sign In again'
                }
            }
    },
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From this, a json web token will be returned to the client. We can use this to authenticate to protected routes on our server. Now, for user experience:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vkgj_lCKPtY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h4&gt;
  
  
  Wrapping Up
&lt;/h4&gt;

&lt;p&gt;** This is just a simple authentication mechanism with Metamask yet effective.&lt;/p&gt;

&lt;p&gt;Find thesource code on GitHub link:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/OliverMengich/web3LoginSendEtherMetamask.git" rel="noopener noreferrer"&gt;https://github.com/OliverMengich/web3LoginSendEtherMetamask.git&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you.**&lt;/p&gt;

</description>
      <category>web3</category>
      <category>frontend</category>
      <category>javascript</category>
      <category>ethereum</category>
    </item>
    <item>
      <title>COMMON API VULNERABILITIES</title>
      <dc:creator>Oliver Kem</dc:creator>
      <pubDate>Mon, 17 Apr 2023 10:53:47 +0000</pubDate>
      <link>https://dev.to/olivermengich/common-api-vulnerabilities-2pkb</link>
      <guid>https://dev.to/olivermengich/common-api-vulnerabilities-2pkb</guid>
      <description>&lt;p&gt;When developing APIs for fortune 500 companies, developers often forget measures that ensure that their APIs don’t expose their data or the architecture of their backend. This measures are so simple to enforce but when neglected it leads to massive breaches of their APIs. for example, forgetting to enforce a rate limiting of reset password functionality which requires a 4-Pin digit code to verify can cause the hacker to end up trying all possible combination of the pin which takes up to 10,000 request. Or allowing an authenticated user to access other user’s data and to perform actions that only an administrator to the website can lead to massive breaches.&lt;/p&gt;

&lt;p&gt;In this blog, I’ll walk you through 8 of the OWASP TOP 10 vulnerabilities and how we can avoid them.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Broken Object Level Authorization Vulnerability
&lt;/h3&gt;

&lt;p&gt;Occurs when an API provider allows an API consumer to access &lt;br&gt;
   resources they are not authorized to access. If an API endpoint &lt;br&gt;
   does not have object-level access controls, it won’t perform &lt;br&gt;
   checks to make sure users can only access their own resources. &lt;br&gt;
   When these controls are missing, User A will be able to &lt;br&gt;
   successfully request User B’s resources. APIs use some sort of &lt;br&gt;
   value, such as names or numbers, to identify various objects. &lt;br&gt;
   When we discover these object IDs, we should test to see if we &lt;br&gt;
   can interact with the resources of other users when &lt;br&gt;
   unauthenticated or authenticated as a different user. For &lt;br&gt;
   instance, imagine that we are authorized to access only the &lt;br&gt;
   user Cloud Strife. We would send an initial GET request to &lt;br&gt;
   &lt;strong&gt;&lt;a href="https://mywebsite.com/api/users?id=100"&gt;https://mywebsite.com/api/users?id=100&lt;/a&gt;&lt;/strong&gt; and receive the following response&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{

“id”: “100”,

“first_name”: “Jane”,

“last_name”: “Doe”,

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But looking at the id, which is 100, Say we are able obtain information about another user by sending a request for &lt;strong&gt;&lt;a href="https://mywebsite.com/api/users?id=101"&gt;https://mywebsite.com/api/users?id=101&lt;/a&gt;&lt;/strong&gt; and receiving the following response&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{

“id”: “101”,

“first_name”: “John”,

“last_name”: “Doe”,

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This vulnerability is also called an IDOR. We can avoid this type of vulnerability by changing the primary key of the user, for example, the id and generating random characters or that are unique identifiable to a specific user&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Information Disclosure
&lt;/h3&gt;

&lt;p&gt;When an API responds with sensitive information with unprivileged users, this is called information disclosure vulnerability. Sensitive data can include any information that attackers can leverage to their advantage. This sensitive data may include the users’ role. For instance, consider the following request:&lt;/p&gt;

&lt;p&gt;{“id”:2,”name”:”Vincent Valentine”, “role”:”admin”}&lt;/p&gt;

&lt;p&gt;Information may be disclosed in API responses or public sources such as code repositories, search results, news, social media, the target’s website, and public API directories.&lt;/p&gt;

&lt;p&gt;Another common information disclosure issue involves verbose messaging. This might include Error messages. These messages can reveal sensitive information about resources, users, and the API’s underlying architecture (such as the version of the web server or database). For example, say you attempt to authenticate to an API and receive an error message such as “Invalid User ID” Next, say you try another email, the error message changes to “incorrect password.” This lets you know that you’ve provided a legitimate user ID for the API. The attacker can then conduct a phishing attack with the user email.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Excessive Data Exposure
&lt;/h3&gt;

&lt;p&gt;Excessive data exposure is when an API endpoint responds with more information than is needed to fulfill a request. When a consumer requests specific information, the provider might respond with all sorts of information, assuming the consumer will then remove any data they don’t need from the response. This vulnerability is equivalent to asking someone for their name and having them respond with their name, date of birth, email address, phone number, and the identification of every other person they know. Consider the following response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{

“id”: “100”

“first_name”: “John”

“last_name”: “Doe”,

“privilege”: “user”,

“representative”: [

“name”: “Don Corneo”,

“id”: “300”

“email”: “dcorn@gmail.com”,

“privilege”: “super-admin”

“admin”: true

“two_factor_auth”: false

]

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Excessive data exposure is one of those awesome API vulnerabilities that bypasses every security control in place to protect sensitive information and hands it all to an attacker on a silver platter simply because they used the API. All you need to do to detect excessive data exposure is test your target API endpoints and review the information sent in response&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Lack of Resources and Rate Limiting
&lt;/h3&gt;

&lt;p&gt;Without limiting the number of requests consumers can make, an API provider’s infrastructure could be overwhelmed by the requests which could lead to a DOS attack. Too many requests without enough resources will lead to the provider’s systems crashing and becoming unavailable — a denial of service (DoS) state. Besides potentially DOS-ing an API, an attacker who bypasses rate limits can cause additional costs for the API provider. Many API providers monetize their APIs by limiting requests and allowing paid customers to request more information. Some API providers also have infrastructure that automatically scales with the quantity of requests. In these cases, an unlimited number of requests would lead to a significant and easily preventable increase in infrastructure costs.&lt;/p&gt;

&lt;p&gt;An attacker can you bypass rate limiting by adding or removing a parameter, using a different client, or altering your IP address&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Broken Function Level Authorization
&lt;/h3&gt;

&lt;p&gt;Broken function level authorization (BFLA) is a vulnerability where a user of one role or group can access the API functionality of another role or group. In other words, BFLA can be a lateral move, where you use the functions of a similarly privileged group, or it could be a privilege escalation, where you are able to use the functions of a more privileged group. Particularly interesting API functions to access include those that deal with sensitive information, resources that belong to another group, and administrative functionality such as user account management.&lt;/p&gt;

&lt;p&gt;BFLA is an authorization problem for performing actions. For example, consider a vulnerable banking API. If a BFLA vulnerability is present, you might be able to transfer money and update the account information. BFLA is about unauthorized actions. If an API has different privilege levels or roles, it may use different endpoints to perform privileged actions. For example, a bank may use the /{user}/account/balance endpoint for a user wishing to access their account information and the /admin/account/{user} endpoint for an administrator wishing to access user account information.&lt;/p&gt;

&lt;p&gt;If the application does not have access controls implemented correctly, we’ll be able to perform administrative actions, such as seeing a user’s full account details, by simply making administrative requests.&lt;/p&gt;

&lt;p&gt;Solving the problem by specifying in the user access token that defines the role of the users or user and restricting the HTTP methods a consumer can use, simply making an unauthorized request with a different method could indicate a BFLA vulnerability. These two methods can help prevent a BFLA vulnerability.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Broken User Authentication
&lt;/h3&gt;

&lt;p&gt;These vulnerabilities occurs when an API does not have a strong authentication protection mechanism or the authentication mechanism is incorrectly configured. API authentication can be a complex system that includes several processes with a lot of room for failure. As developers, we often pass authorization tokens through HTTP headers of even request parameters and store then in the client side(browser) as cookies. An attacker can detect hardcoded tokens and once he finds the token, he can use it to gain access to previously hidden endpoints or to bypass detection.&lt;/p&gt;

&lt;p&gt;The other authentication processes that could have their own set of vulnerabilities include aspects of the registration system, such as the password reset and multifactor authentication features. For example, Consider a password reset feature requires you to provide an email address and a 4-digit verification code to reset your password. Well, if the API allowed you to make as many requests as you wanted, you’d only have to make one million requests in order to guess the code and reset any user’s password. A four-digit code would require only 10,000 requests.&lt;/p&gt;

&lt;p&gt;These however can be corrected by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Rate limiting when authenticating&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Avoid over exposure and verbose error messaging&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accessing resources after authenticated&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, code committed to a GitHub repository could reveal a hardcoded admin API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;“oauth_client”: [

{

“client_id”: “12345-abcd”,

“client_type”: “admin”,

“api_key”: “AIzaSyDrbTFCeb5k0yPSfL2heqdF-N19XoLxdw”

}

]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Due to the stateless nature of REST APIs, a publicly exposed API key is the equivalent of discovering a username and password. By using an exposed API key, you’ll assume the role associated with that key.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Injections
&lt;/h3&gt;

&lt;p&gt;Injection flaws exist when a request is passed to the API and the API provider doesn’t do filter the input to remove unwanted characters. This flaw can cause SQL injection, NoSQL injection, and system command injection to your database and even backend infrastructure. If an send a payload containing SQL commands to a vulnerable API that uses a SQL database, the API will pass the commands to the database, which will process and perform the commands. The same will happen with vulnerable NoSQL databases and affected systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Improper Assets Management
&lt;/h3&gt;

&lt;p&gt;Improper assets management takes place when an organization exposes APIs that are either retired or still in development. Improper assets management can lead to other vulnerabilities, such as excessive data exposure, information disclosure, mass assignment, improper rate limiting, and API injection. For attackers, this means discovering an improper assets management vulnerability is only the first step toward further exploitation of an API. An attacker can discover improper assets management by paying close attention to outdated API documentation, changelogs, and version history on repositories. Developers often include versioning information in their endpoint names to distinguish between older and newer versions, such as /v1/, /v2/, /v3/, and so on. APIs still in development often use paths such as /alpha/, /beta/, /test&lt;/p&gt;

&lt;h4&gt;
  
  
  References
&lt;/h4&gt;

&lt;p&gt;Hacking APIs: Breaking Web Application Programming Interfaces by Corey Ball. &lt;a href="https://nostarch.com/hacking-apis"&gt;https://nostarch.com/hacking-apis&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>security</category>
      <category>webdev</category>
      <category>backend</category>
    </item>
    <item>
      <title>Displaying dynamic JSON data in GatsbyJS</title>
      <dc:creator>Oliver Kem</dc:creator>
      <pubDate>Sat, 15 Apr 2023 06:40:51 +0000</pubDate>
      <link>https://dev.to/olivermengich/displaying-dynamic-json-data-in-gatsbyjs-4ag3</link>
      <guid>https://dev.to/olivermengich/displaying-dynamic-json-data-in-gatsbyjs-4ag3</guid>
      <description>&lt;p&gt;GatsbyJS is an amazing tool to help leverage when building website. GatsbyJS offers amazing features like the built in GraphQL tool to help in queries for files inside the filesystem and retrieve data without the need of reading the data. This is an amazing feature in terms of optimized application performance. GraphQL also offers libraries like &lt;code&gt;gatsby-source-dev&lt;/code&gt; that helps retrieve data from the &lt;a href="//dev.to"&gt;Dev.to&lt;/a&gt; website.&lt;br&gt;
In a later session, I will show us how to fetch data from dev.to using markdown feature. For today, let us learn how we can use &lt;code&gt;gatsby-transform-json&lt;/code&gt; to retrieve data and display it in our application.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Javascript&lt;/li&gt;
&lt;li&gt;Knowledge with React&lt;/li&gt;
&lt;li&gt;Typescript (But not necessary)&lt;/li&gt;
&lt;li&gt;GatsbyJS (But not necessary)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this information. Let's dive into it &lt;/p&gt;

&lt;p&gt;We first need to initiialize an new application. Let's go into our terminal and run the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm init gatsby
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This this in your terminal and follow the prompt. I am using the &lt;code&gt;src&lt;/code&gt; directory because I find it awesome having all files in one folder.&lt;br&gt;
 I am creating my portfolio website and I want to display the list of projects I have done in my projects page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd my-portfolio
$ npm run develop 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This spins up a server in &lt;code&gt;localhost:8000&lt;/code&gt; and a Graphql server at &lt;code&gt;localhost:8000/__graphql&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I had already set up my project before. Just create a folder inside the &lt;code&gt;src&lt;/code&gt; and name it &lt;code&gt;projects&lt;/code&gt;. Then add a folder called &lt;code&gt;images&lt;/code&gt; inside and a file called &lt;strong&gt;&lt;em&gt;&lt;code&gt;products.json&lt;/code&gt;&lt;/em&gt;&lt;/strong&gt;. When you create a new gatsby project, it comes with some default plugins contained in the &lt;strong&gt;&lt;em&gt;&lt;code&gt;gatsby-config.ts&lt;/code&gt;&lt;/em&gt;&lt;/strong&gt; file. Let's take a look at it&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbsaz64bdvtd0gxmmfdu6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbsaz64bdvtd0gxmmfdu6.png" alt="Image of Gatsby-config.ts file"&gt;&lt;/a&gt;&lt;br&gt;
When you Query for the site's metadata, it is returns the title and siteurl, but we will not look at that.&lt;br&gt;
Inside the plugins' array, there are default plugins like  &lt;code&gt;"gatsby-plugin-mdx"&lt;/code&gt;, &lt;code&gt;gatsby-plugin-sharp"&lt;/code&gt;, &lt;code&gt;"gatsby-transformer-sharp"&lt;/code&gt; that comes preinstalled.&lt;br&gt;
But for us, we will need to interact with our &lt;code&gt;json&lt;/code&gt; data. So we need to add a few new plugin called &lt;code&gt;gatsby-transformer-remark&lt;/code&gt; and &lt;code&gt;gatsby-transformer-json&lt;/code&gt;. These libraries help us interact with the  &lt;code&gt;JSON&lt;/code&gt; data.&lt;br&gt;
Go to your terminal and run the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install gatsby-transformer-remark gatsby-transformer-json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once installed, add this to your &lt;strong&gt;&lt;em&gt;&lt;code&gt;gatsby-config.ts&lt;/code&gt;&lt;/em&gt;&lt;/strong&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6u2qflbke82e65vy5dc2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6u2qflbke82e65vy5dc2.png" alt="GatsbyJS image with transformer-json added"&gt;&lt;/a&gt;&lt;br&gt;
Now we are all set. But there's one more thing to add. We need to give our GraphQL server permission to access the &lt;code&gt;projects&lt;/code&gt; folder we created. So lets do that. Inside our &lt;strong&gt;&lt;em&gt;&lt;code&gt;gatsby-config.ts&lt;/code&gt;&lt;/em&gt;&lt;/strong&gt;, add the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    resolve: 'gatsby-source-filesystem',
    options: {
      "name": "projects",
      "path": "./src/projects/"
    },
    __key: "projects"
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, it can access the &lt;code&gt;projects&lt;/code&gt; folder. Your code should be like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F28d9l0dwnfy529vviz77.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F28d9l0dwnfy529vviz77.png" alt="Updated with Projects folder view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's add a files inside the projects folder called &lt;code&gt;projects.json&lt;/code&gt; and will store our projects information, let's add some info. Let's also create a file called &lt;code&gt;images&lt;/code&gt; inside the projects folder. We will store images for our projects here.&lt;br&gt;
&lt;code&gt;projects/images&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;src/projects/projects.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
[
    {
        "title":"Project 1",
        "description":"My first project",
        "imageUrl":"./images/image1.png",
        "url":"https://example.com/image1.png"
    },
    {
        "title":"Project 2",
        "description":"My second project",
        "imageUrl":"./images/image2.png",
        "url":"https://example.com/image2.png"
    },
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this in set, let's go on and start working on our code.&lt;/p&gt;

&lt;p&gt;Go to the terminal and spin up your development server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm run develop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GatsbyJS spins up a development server at &lt;code&gt;localhost:8000&lt;/code&gt; where you can view your app. GatsbyJS also offers a GraphQL playground where you can interact with your files in your projects, this is amazing because it helps interact with files and at the same times Gatsby offers other plugin libraries e.g &lt;code&gt;gatsby-source-dev&lt;/code&gt;and &lt;code&gt;gatsby-source-hashnode&lt;/code&gt; which helps fetch from &lt;a href="//dev.to"&gt;Dev.to&lt;/a&gt; and &lt;a href="//hashnode.com"&gt;Hashnode&lt;/a&gt;, API to fetch for blog posts, but these two are just to name a few, you can search for all plugins&lt;/p&gt;

&lt;p&gt;To view your GraphQL playground go to &lt;code&gt;localhost:8000/___graphql&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When you visit through this url, you find a nice graphql playground. With this playground, you can query for information and files in your folder, this is amazing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsf1fwcsqa5grm1rhfz3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsf1fwcsqa5grm1rhfz3.png" alt="Image for GraphQL Playground"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will also see &lt;code&gt;allProjectsJson&lt;/code&gt;, this of course depends on what you named your json file, but with this, you can query for information in your json file. I will be adding a file called &lt;code&gt;projects.tsx&lt;/code&gt; in my application. This will be the route for my application's projects page.&lt;/p&gt;

&lt;p&gt;Now let's query for some stuff &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fablngjvis1epb5q4ddty.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fablngjvis1epb5q4ddty.png" alt="Json file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've just query for the information in our file. When we type in the query, we get some information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvfl47n1313a6c1tvbkoa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvfl47n1313a6c1tvbkoa.png" alt="Information Query"&gt;&lt;/a&gt;&lt;br&gt;
Let's now add this to our project's file.&lt;br&gt;
Go to your &lt;code&gt;projects.tsx&lt;/code&gt; file and write this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as React from "react"
import { HeadFC, PageProps, useStaticQuery, graphql } from "gatsby"
import ProjectsList from "../components/Projects/Projects.component";
import Footer from "../components/Footer/Footer.component";
const IndexPage: React.FC&amp;lt;PageProps&amp;gt; = () =&amp;gt; {
    const data = useStaticQuery(graphql`
        query MyQuery {
        allProjectsJson {
            edges {
                node {
                    id
                    title
                    description
                    url
                    imageUrl {
                        childImageSharp {
                            fluid(maxWidth: 700) {
                                srcSet
                                src
                                base64
                                aspectRatio
                                sizes
                            }
                        }
                    }
                }
            }
        }
    }
    `)
    console.log(data);
    return (
        &amp;lt;Layout&amp;gt;
            &amp;lt;PageInfoComponent title="Projects" path="projects"/&amp;gt;
            &amp;lt;ProjectsList
                projects={data.allProjectsJson.edges}
            /&amp;gt;
            &amp;lt;Footer/&amp;gt;
        &amp;lt;/Layout&amp;gt;
    )
}

export default IndexPage

export const Head: HeadFC = () =&amp;gt; &amp;lt;title&amp;gt;Projects &amp;lt;/title&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now in our &lt;code&gt;Projects.component.tsx&lt;/code&gt; file, let's add the following line of code.&lt;br&gt;
So here, Loop through the information provided and display them here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import styled from 'styled-components';
import Image from 'gatsby-image';


type ProjectsListProps = {
    projects: any[],
};
function ProjectsList({projects, theme}: ProjectsListProps) {
    return (
        &amp;lt;&amp;gt;
            {
                projects.map((edge: any) =&amp;gt; (
                    &amp;lt;div 
                       key={edge.node.id}&amp;gt;
                        &amp;lt;h1&amp;gt;{edge.node.title}&amp;lt;/h1&amp;gt; 
                        &amp;lt;Image fluid={edge.node.imageUrl.childImageSharp.fluid} alt={edge.node.title} /&amp;gt;
                        &amp;lt;p style={{
                            color: theme?.color
                        }}&amp;gt;
                            {edge.node.description}
                        &amp;lt;/p&amp;gt;
                        &amp;lt;a href={edge.node.url}&amp;gt;Learn More &amp;lt;/a&amp;gt;
                    &amp;lt;/div&amp;gt;
                ))
            }
        &amp;lt;/&amp;gt;
    );
}
export default ProjectsList;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;useStaticQuery&lt;/code&gt; is a hook that is used. The &lt;code&gt;graphql&lt;/code&gt; allows us to query for the information. This is cool. &lt;br&gt;
You can add your styling there to display the information.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>gatsby</category>
      <category>react</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Integrating Credentials Provider with NextAuthJS and MongoDB with Typescript - Part 1</title>
      <dc:creator>Oliver Kem</dc:creator>
      <pubDate>Sat, 08 Apr 2023 08:45:43 +0000</pubDate>
      <link>https://dev.to/olivermengich/integrating-credentials-provider-with-nextauthjs-and-mongodb-with-typescript-4a25</link>
      <guid>https://dev.to/olivermengich/integrating-credentials-provider-with-nextauthjs-and-mongodb-with-typescript-4a25</guid>
      <description>&lt;p&gt;Authentication and Authorization in modern application is very essentials because you are managing user data, but it can be a bit sketchy sometimes as we have to consider route protection, session management, protecting several routes/pages, password encryption, validating user's credentials during sign-up and sign-in. &lt;/p&gt;

&lt;p&gt;Next Auth is an open source, free library that handles authentication tasks for the developer like JWT, cookie. It also enables OAUTH2.0 providers like Twitter, GitHub, Google, Facebook and Discord.&lt;/p&gt;

&lt;p&gt;Next Auth handles session management and this improves the security of your application by implementing built in security features so that the server can't be tricked easily &lt;/p&gt;

&lt;p&gt;In this tutorials, we are going to look at how to implement email password authentication on users' credentials like email and password.&lt;/p&gt;

&lt;h3&gt;
  
  
  Table Of Contents
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    * [Create NextJS App](#chapter-1)
    * [Installing Dependencies](#chapter-2)
    * [User Sign Up](#chapter-3)
    * [Sign In](#chapter-4)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Packages to Install
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mongoose&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;next-auth&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bycryptjs&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Creating The NextJS Application &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;I will be using &lt;code&gt;pnpm&lt;/code&gt; but be free to use &lt;code&gt;npm&lt;/code&gt; if you like. Go to your terminal and run the following line of code&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$pnpm create next-app --typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We Initialize the application with typescript&lt;br&gt;
Follow the Prompt on the command line to create the NextJS Application. I will not be using the app directory that comes with &lt;a href="https://nextjs.org/docs/getting-started"&gt;&lt;code&gt;NextJS 13&lt;/code&gt;&lt;/a&gt;, I will also be using the &lt;code&gt;src&lt;/code&gt; directory with NextJS, but fill free to use it to your own liking.&lt;/p&gt;
&lt;h3&gt;
  
  
  Installing Dependencies &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;After successfully creating the nextJS application, we install the dependencies, go to your terminal and run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$pnpm add mongoose next-auth bcryptjs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will be using a local instance of mongodb server, so we fetch the URL&lt;br&gt;
I will not show how to install mongodb on your pc, feel free to use the database you like&lt;br&gt;
Create a &lt;code&gt;.env.development&lt;/code&gt; file in the root folder, then paste the following line of code&lt;br&gt;
&lt;code&gt;MONGODB_URL="mongodb://localhost:27017/test_db"&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Model and Controller &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;NextJS provides us to write API codes in the &lt;code&gt;pages/api&lt;/code&gt; folder using the NodeJS environment. It will also follow the same folder-structured route. Create a folder in the &lt;code&gt;api&lt;/code&gt; folder and call it &lt;code&gt;auth&lt;/code&gt;. Create a route &lt;code&gt;pages/api/auth/sign-up.ts&lt;/code&gt;. We also need to make sure that only the POST method is accepted and nothing else.&lt;/p&gt;

&lt;p&gt;But before we start working the the route, let's create a user model that we can use to define the components of user&lt;br&gt;
Create a folder called &lt;code&gt;utils&lt;/code&gt;. Inside the folder, create a file called &lt;code&gt;user.model.ts&lt;/code&gt;. Then paste the following line of code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mongoose, { Document } from 'mongoose';

const userSchema = new mongoose.Schema({
    name: {
      type: String,
      required: true,
    },
    age: {
      type: Number,
      required: true,
    },
    email: {
      type: String,
      required: true,
      unique: true,
    },
    password: {
      type: String,
      required: true,
    },
  },
  { timestamps: true }
);

export interface IUser extends Document {
    name: string;
    age: number;
    email: string;
    password: string;
    createdAt: Date;
    updatedAt: Date;
}
let UserModel: mongoose.Model&amp;lt;IUser&amp;gt;;
try {
  // Try to get the existing model from mongoose
  UserModel = mongoose.model&amp;lt;IUser&amp;gt;('User');
} catch {
  // If the model doesn't exist, define it
  UserModel = mongoose.model&amp;lt;IUser&amp;gt;('User', userSchema);
}
export default UserModel;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we have defined the user model and its contents, we also export the user Interface so that we can use it somewhere else. &lt;/p&gt;

&lt;p&gt;We also need to handle sign in to mongodb database. Let's create a file and call it &lt;code&gt;db.ts&lt;/code&gt;. Paste in the following line of code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mongoose from "mongoose";
//connect to mongodb
const connectionUrl = "mongodb://localhost:27017/test_db";
const connectDB = async () =&amp;gt; {
    try {
        const conn = await mongoose.connect(process.env.MONGODB_URI||connectionUrl);
        console.log(`MongoDB Connected: ${conn.connection.host}`);
    } catch (err) {
        console.error('Error Encountered: ',err);
        process.exit(1);
    }
};
export default connectDB;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now lets create a controller file inside the &lt;code&gt;utils&lt;/code&gt; folder, name it &lt;code&gt;user.controller.ts&lt;/code&gt;. Now lets paste the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import UserModel from './user.model';
type UserX = Omit&amp;lt;IUser,  | 'createdAt' | 'updatedAt' &amp;gt;;
export const createUser = async (user: UserX) =&amp;gt; {
    console.log('Request to add user: ', user)
    console.log(await connectDB());
    const userAdded: UserX = {
        ...user,
        password: bcryptjs.hashSync(user.password, 10),
        userType: 'PATIENT',
    }
    console.log('Request to add user: ', userAdded);
    const finduser = await UserModel.findOne({
        email: userAdded.email
    });
    if(finduser) throw new Error("User Found, Change Email");
    const newUser = await UserModel.create(userAdded);
    return newUser;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will use this controller file to sign up to our application. Now back to our &lt;code&gt;sign-up.ts&lt;/code&gt; file, we need to handle this authentification, open the file and paste the following line of code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import type { NextApiRequest, NextApiResponse } from 'next';
import { createUser } from '../controllers/user.controller';
type Data = {
  message: string
}

export default async function handler(req: NextApiRequest, res: NextApiResponse&amp;lt;Data&amp;gt;) {
    if (req.method==='POST') {
        const {email, password, ...otherProps} = req.body;
        if (!email || !email.includes('@') || !password) {
            res.status(422).json({ message: 'Invalid Data' });
            return;
        }
        const data = await createUser({email, password, ...otherProps})
        if (!data) {
            res.status(422).json({ message: 'User already exists' });
            return;
        }
        // sign in the user
        res.status(201).json({ message: 'User created',...data });
        return
    }else{
        res.status(500).send({message:'Invalid Route'})
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We import our user controller file, this is where we will write our API. We destructure the email and password then validate if the user exists, if not we create the user, we then hash the password. If user exists, we throw the error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sign In &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Now we need to handle the sign in route for the user.&lt;/p&gt;

&lt;p&gt;Next-Auth provides us with Client API as well as REST API&lt;br&gt;
The &lt;strong&gt;NextAuth.js client&lt;/strong&gt; library makes it easy to interact with sessions from React applications.&lt;/p&gt;

&lt;p&gt;NextAuth.js exposes a REST API which is used by the NextAuth.js client. &lt;br&gt;
We will use both for signing in the users.&lt;/p&gt;

&lt;p&gt;To add NextAuth.js to a project create a file called &lt;code&gt;[...nextauth].ts&lt;/code&gt; in &lt;code&gt;pages/api/auth.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;All requests to /api/auth/* (signin, callback, signout, etc) will automatically be handed by NextAuth.js.&lt;/p&gt;

&lt;p&gt;Before we will need to handle the sign in the user, so we should update our controller file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const getUserByEmail = async (email: string) =&amp;gt; {
    const user: UserX | null = await UserModel.findOne({
        email
    });
    if(!user) throw new Error("No User Found");
    return user;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this help from next-auth, we need to implement our own sign-in logic for checking users stored on the database.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;[...nextauth].ts&lt;/code&gt; file, paste in the following lines of code. I will walk you write through it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import NextAuth, {NextAuthOptions, Session, User} from 'next-auth';
import Credentials from 'next-auth/providers/credentials';
import { getUserByEmail } from '../controllers/user.controller';
import { IUser } from '../users';
import bcrypt from 'bcryptjs';
import { NextApiHandler } from 'next';
import { getDoctorByStaffID } from '../controllers/doctor.controller';
interface Credentials{
  email: string;
  password: string;
}
export interface MySession extends Session{
    user:{
        id: string,
        name: string,
        email: string,
        phone: string,
        isAdmin: boolean,
        image: string
    }
}
interface MyUser extends User{
    id: string,
    name: string,
    email: string,
    phone: string,
    isAdmin: boolean,
}
export const options: NextAuthOptions = {
    session:{
        strategy: 'jwt',
    },
    callbacks: {
        async jwt({token, user}) {
            if (user) {
                token.user = user;
            }
            return token;
        },
        async session({ session,token }){
            if (token) {
                session.user = token.user as MyUser;
            }
            return Promise.resolve(session);
        },
    },
    secret: process.env.MONGODB_URI,
    providers: [
        Credentials({
            id: 'credentials',
            name: 'credentials',
            credentials:{
                email: {label:'email', type:'text',placeholder:''},
                password:{label:'password',type:'password'}
            },
            async authorize(credentials){
                const { email, password } = credentials as Credentials;
                const user: IUser| null = await getUserByEmail(email);
                if (!user) {
                    throw new Error("No User Found");
                }
                const isMatch = await bcrypt.compare(password, user.password);
                if (!isMatch) {
                    throw new Error("Password doesnt Match");
                }
                return {
                    id: user._id,
                    name: user.name,
                    email: user.email,
                };
            },
        })
    ],
}
const Handler: NextApiHandler = (req, res) =&amp;gt; NextAuth(req, res, options);
export default Handler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code is compatible with NextAuth.js version 4. Here, we import the Credentials provider, this allows us to define a sign in with password and email.  Inside the &lt;code&gt;authorize()&lt;/code&gt; function we pass in the email and password we had defined as input. we then return the user information. In the callback functions, we have the &lt;code&gt;session()&lt;/code&gt; and &lt;code&gt;jwt()&lt;/code&gt; function. this takes in the user we had returned in the &lt;code&gt;authorize()&lt;/code&gt; so we can define all this. We used type assertions for defining its return type.&lt;/p&gt;

&lt;p&gt;In the next session, we will continue with the client side.&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>nextjs</category>
      <category>typescript</category>
      <category>nextauth</category>
    </item>
  </channel>
</rss>
