نئی تاریخ

DIY Real-Time Polling اپلی کیشن Supabase اور Permit.io کے ساتھ رسائی کو بند کرتا ہے

کی طرف سے Permit.io40m2025/04/16
Read on Terminal Reader

بہت لمبا؛ پڑھنے کے لئے

ایک محفوظ، حقیقی وقت میں ووٹنگ اپلی کیشن کی تعمیر کے لئے ایک مکمل سٹاک گائیڈ، تصدیق، فی صارف کی اجازتیں، اور متحرک پالیسی چیک - Supabase + Permit.io کا استعمال کرتے ہوئے.
featured image - DIY Real-Time Polling اپلی کیشن Supabase اور Permit.io کے ساتھ رسائی کو بند کرتا ہے
Permit.io HackerNoon profile picture
0-item


By گابریل L. Manor

گابریل L. مانور


Supabase ای میل، OAuth، اور جادو لنکس کے لئے داخلہ کی حمایت کے ساتھ آپ کے ایپ میں تصدیق کو شامل کرنے کے لئے آسان بناتا ہے. لیکن اگرچہ Supabase Auth آپ کے صارفین کے بارے میں کام کرتا ہے، تو آپ کو اکثر ایک تصدیق کی سطح کی ضرورت ہوتی ہے.


Supabase میں داخلہ auth اور Row Level Security (RLS) کے ساتھ ایک عظیم بیک اینڈ پیش کرتا ہے، fine-grained اجازتیں - خاص طور پر صارفین اور اعداد و شمار کے درمیان تعلقات پر مبنی - آسان سے دور ہے.

فائدہ مند خصوصیاتصارفین اور ڈیٹا کے درمیان تعلقات


آپ کو ڈیٹا کو ترمیم یا حذف کرنے جیسے کارروائیوں کو وسائل کے مالکان کو محدود کرنا چاہئے، صارفین کو ان کے اپنے مواد پر ووٹ کرنے سے روکنے، یا مختلف صارف کرداروں کے لئے مختلف اجازتوں کو نافذ کرنے سے روکنا چاہئے.


یہ ٹیوٹوریل ایک Next.js ایپلی کیشن میں Supabase تصدیق اور لائسنس کو کیسے لاگو کرنے کے بارے میں جانتا ہے.

Supabase تصدیق اور لائسنسNext.js کے بارے میں

We'll start with Supabase Auth for login and session management, then add authorization rules using Relationship-Based Access Control (ReBAC), enforced through Supabase Edge Functions and a local Policy Decision Point (PDP).

سائپ بیس آؤٹمقاصد کی اجازتRelationship-Based Access Control (ReBAC)Supabase Edge Functionslocal Policy Decision Point (PDP)


آخرت میں، آپ کو ایک حقیقی وقت میں مشترکہ سروے کے ایپلی کیشن مل جائے گا جو دونوں عوامی اور محفوظ کارروائیوں کو حمایت کرتا ہے - اور ایک انعطاف پذیر اجازت کے نظام آپ کے ایپلی کیشن کی ترقی کے ساتھ ترقی کرسکتے ہیں.

آپ کیا کر رہے ہیں

اس گائیڈ میں، ہم Supabase اور Next.js کا استعمال کرتے ہوئے ایک حقیقی وقت میں ووٹنگ اپلی کیشن بنائیں گے جو کارروائی میں تصدیق اور مجازیت دونوں کو دکھاتا ہے.

سائپ بیسNext.js کے بارے میں


آپ کا استعمال کرتے ہوئے صارفین کو سروے بنانے، دوسروں پر ووٹ دینے اور صرف ان کے اپنے مواد کا انتظام کرنے کی اجازت دیتا ہے. یہ دکھاتا ہے کہ کس طرح Supabase Auth لاگ ان / سائن اپ کے لئے لاگو کیا جا سکتا ہے اور کس طرح آپ کی اجازت کی پالیسی کو لاگو کیا جا سکتا ہے جو کس کو ووٹ، ترمیم، یا حذف کر سکتا ہے.

سائپ بیس آؤٹآپ کی اجازت کی پالیسی


We will use Supabase’s core features—Auth، Postgres، RLS، Realtime، اور Edge Functions—combined with a Relationship-Based Access Control (ReBAC) model to enforce per-user and per-resource access rules.

آپبھارتیںrls کے بارے میںRealtime کے بارے میںایڈج فیکٹریز رشتے پر مبنی رسائی کنٹرول (ReBAC)

تکنیکی Stack

  • Supabase – Backend-as-a-service for database, authentication, realtime, and edge functions
  • Next.js – Frontend framework for building the app UI and API routes
  • Permit.io – (for ReBAC) to define and evaluate authorization logic via PDP
  • Supabase CLI – To manage and deploy Edge Functions locally and in production
  • Supabase – Backend-as-a-service for database, authentication, realtime, and edge functions
  • SupabaseSupabase
  • Next.js – Frontend framework for building the app UI and API routes
  • Next.jsNext.js
  • Permit.io – (for ReBAC) to define and evaluate authorization logic via PDP
  • Permit.ioPermit.io
  • Supabase CLI – To manage and deploy Edge Functions locally and in production
  • Supabase CLISupabase CLI

    مقاصد

  • Node.js نصب کیا گیا
  • Supabase اکاؤنٹ
  • Permit.io account
  • Permit.io
  • React/Next.js کے ساتھ واقفیت
  • Starter project repo
  • Starter project repo

    اس اپلی کیشن کیا کر سکتا ہے؟

    ڈیمو ایپلی کیشن ایک حقیقی وقت میں ووٹنگ پلیٹ فارم ہے جو Next.js اور Supabase کے ساتھ تعمیر کیا گیا ہے، جہاں صارفین ووٹ بن سکتے ہیں اور دوسروں پر ووٹ کرسکتے ہیں.


    • کسی بھی صارف (مصمم یا نہیں) عوامی سروے کی فہرست دیکھ سکتا ہے
    • ایک صارف صرف تصدیق شدہ صارفین کو سروے بنا سکتے ہیں اور ووٹ کر سکتے ہیں
    • ایک صارف اپنے پیدا کردہ سروے پر ووٹ نہیں کر سکتا
    • ایک صارف ایک سروے کا تخلیق کرنے والا صرف اسے ترمیم یا حذف کر سکتا ہے
  • کسی بھی صارف (مجاز یا نہیں) عوامی سروے کی فہرست دیکھ سکتے ہیں
  • صرف تصدیق شدہ صارفین کو سروے بنانے اور ووٹنگ کر سکتے ہیں
  • A user cannot vote on a poll they created
  • آپ نے تخلیق شدہ سروے پر ووٹ نہیں کر سکتے
  • ایک سروے کا صرف تخلیق کرنے والا اسے ترمیم یا حذف کر سکتا ہے
  • creator of a poll کا ترجمہ

    تصویریں

    ہم ان عام اقدامات پر عمل کریں گے:


    1. Project، Schema، auth، and RLS
    2. Build core app features like poll creation and voting
    3. Model authorization rulesPermit.io
    4. Create Supabase Edge Functions for syncing users, allocating roles, and checking permissions
    5. Enforce policies in the app frontend using those edge functions
  • Setup Supabase پروجیکٹ، اسکیم، auth، اور RLS
  • Supabase کو ترتیب دیں
  • ایپ کے بنیادی خصوصیات کو بنائیں جیسے سروے کی تخلیق اور ووٹنگ
  • Build core app features کا استعمال کریں
  • ماڈل لائسنس کے قوانین Permit.io میں کردار اور قوانین کا تعین کریں
  • ماڈل کی اجازت کے قوانین
  • Supabase Edge Functions کا تخلیق کریں صارفین کو سائن اپ کرنے، کردار ادا کرنے، اور اجازتوں کو چیک کرنے کے لئے
  • Create Supabase Edge Functions
  • آپ ان کنٹینڈز کو استعمال کرتے ہوئے ایپ فینڈ میں پالیسیوں کو یقینی بنائیںتصحیح کی پالیسی


    آپ شروع کریں -

    Project میں Supabase کی تشکیل

    Project میں Supabase کی تشکیل

    مختصر: شروع کرنے والے ٹیبلٹ کو کلون کریں

    I've already created a starter template on GitHub with all the code you need to start so we can focus on implementing Supabase and Permit.io.

    starter templateGitHub کے لئے


    آپ مندرجہ ذیل کمانڈ کو چلانے کے ذریعے منصوبہ کو کلن کرسکتے ہیں:


    github <https://github.com/permitio/supabase-fine-grained-authorization> 
    git clone <https://github.com/permitio/supabase-fine-grained-authorization>


    ایک بار جب آپ نے منصوبے کو کلون کیا ہے تو، منصوبے کے ڈائریکٹری پر براہ مہربانی براہ مہربانی براہ مہربانی انسٹال کریں:


    cd realtime-polling-app-nextjs-supabase-permitio npm install 
    cd realtime-polling-app-nextjs-supabase-permitio npm install

    Supabase میں ایک نیا پروجیکٹ بنانے

    شروع کرنے کے لئے:

    • Go to https://supabase.com and sign in or create an account.

    • Click "New Project" and fill in your project name, password, and region.

    • Once created, go to Project Settings → API and note your Project URL and Anon Key — you’ll need them later.


  • Go to https://supabase.com and sign in or create an account.

  • Go to https://supabase.com and sign in or create an account.

    https://supabase.com
  • Click "نئی پروجیکٹ" اور اپنے پروجیکٹ کا نام، پاس ورڈ، اور علاقے درج کریں.

  • Click "نئی پروجیکٹ" اور اپنے پروجیکٹ کا نام، پاس ورڈ، اور علاقے درج کریں.

    "نئی منصوبہ"
  • ایک بار پیدا ہونے کے بعد، Project Settings → API پر جائیں اور اپنے Project URL اور Anon Key کو نوٹ کریں - آپ کو بعد میں ان کی ضرورت ہوگی.


  • ایک بار پیدا ہونے کے بعد، Project Settings → API پر جائیں اور اپنے Project URL اور Anon Key کو نوٹ کریں - آپ کو بعد میں ان کی ضرورت ہوگی.

    پروجیکٹ ترتیبات → APIProject URL کے بارے میں معلوماتAnon Key کے بارے میں


    Supabase میں تصدیق اور ڈیٹا بیس کی تشکیل

    We will use Supabase’s built-in email/password auth:

    • ایک طرف کی بار میں آیٹسٹنگ → سپلائرز

    • Email سپلائر کو فعال کریں

    • (مختصر) ٹیسٹ کے لئے ای میل کی تصدیق کو غیر فعال کریں، لیکن پیداوار کے لئے اس کو فعال رکھیں


  • بچے کی بار میں آٹوٹیشن → سپلائرز

  • بچے کی بار میں آٹوٹیشن → سپلائرز

    پر جائیںتصویری → سپلائرز
  • آپ کو Email فراہم کرنے کی اجازت دیں

  • آپ کو Email فراہم کرنے کی اجازت دیں

    ای میل
  • (مختصر) ٹیسٹ کے لئے ای میل کی تصدیق کو غیر فعال کریں، لیکن پیداوار کے لئے اسے فعال رکھیں


  • (مختصر) ٹیسٹ کے لئے ای میل کی تصدیق کو غیر فعال کریں، لیکن پیداوار کے لئے اسے فعال رکھیں


    DataBase Schema کی تخلیق

    یہ اپلی کیشن تین اہم ٹیبلز کا استعمال کرتا ہے: polls، options، اور votes.pollsoptionsvotes SQL ایڈیٹر


    -- ایک سروے ٹیبل بنائیں CREATE TABLE polls ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY, question TEXT NOT NULL, created_by UUID REFERENCES auth.users(id) NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc', NOW()), creator_name TEXT NOT NULL, expires_at TIMESTAMP WITH TIME ZONE NOT NULL, ); -- ایک اختیارات ٹیبل بنائیں CREATE TABLE options ( UUID IDFAULT uuid_generate_v4() PRIMARY KEY, pollid UUID REFERENCES polls(id) ON DELETE CASCADE-- Create a polls table
    CREATE TABLE polls (
        id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
        question TEXT NOT NULL,
        created_by UUID REFERENCES auth.users(id) NOT NULL,
        created_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc', NOW()),
        creator_name TEXT NOT NULL,
        expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
    );
    
    -- Create an options table
    CREATE TABLE options (
        id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
        poll_id UUID REFERENCES polls(id) ON DELETE CASCADE,
        text TEXT NOT NULL,
    );
    
    -- Create a votes table
    CREATE TABLE votes (
        id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
        poll_id UUID REFERENCES polls(id) ON DELETE CASCADE,
        option_id UUID REFERENCES options(id) ON DELETE CASCADE,
        user_id UUID REFERENCES auth.users(id),
        created_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc', NOW()),
        UNIQUE(poll_id, user_id)
    );
    

    Row Level Security (RLS) کی اجازت دیتا ہے

    Enable RLS for each table and define policies:

    RLS
    -- Polls policies ALTER TABLE polls ENABLE ROW LEVEL SECURITY; CREATE POLICY "Anyone can view polls" ON polls FOR SELECT USING (true); CREATE POLICY "Anyone can view options" ON options FOR SELECT USING (true); CREATE POLICY "Poll creators can add options" ON OPTIONS FOR INSERT TO AUTHENTIZED WITH CHECK (auth.uid() = created_by); -- OPTIONS POLICY ALTER TABLE options ENABLE ROW LEVEL SECURITY (EXISTS (SELECT 1 FROM polls WHERE votes idERE = options.pollid_IDECECT AND created auth_by auth-- Polls policies
    ALTER TABLE polls ENABLE ROW LEVEL SECURITY;
    
    CREATE POLICY "Anyone can view polls" ON polls
        FOR SELECT USING (true);
    
    CREATE POLICY "Authenticated users can create polls" ON polls
        FOR INSERT TO authenticated
        WITH CHECK (auth.uid() = created_by);
    
    -- Options policies
    ALTER TABLE options ENABLE ROW LEVEL SECURITY;
    
    CREATE POLICY "Anyone can view options" ON options
        FOR SELECT USING (true);
    
    CREATE POLICY "Poll creators can add options" ON options
        FOR INSERT TO authenticated
        WITH CHECK (
            EXISTS (
                SELECT 1 FROM polls
                WHERE id = options.poll_id
                AND created_by = auth.uid()
            )
        );
    
    -- Votes policies
    ALTER TABLE votes ENABLE ROW LEVEL SECURITY;
    
    CREATE POLICY "Anyone can view votes" ON votes
        FOR SELECT USING (true);
    
    CREATE POLICY "Authenticated users can vote once" ON votes
        FOR INSERT TO authenticated
        WITH CHECK (
            auth.uid() = user_id AND
            NOT EXISTS (
                SELECT 1 FROM polls
                WHERE id = votes.poll_id
                AND created_by = auth.uid()
            )
        );
    


    Supabase کے حقیقی وقت کی خصوصیات کا استعمال کرنے کے لئے:

    • In the sidebar, go to Table Editor


    • For each of the three tables (polls, options, votes):

      • Click the three dots → Edit Table

      • Toggle "Enable Realtime"

      • Save changes


  • In the sidebar, go to Table Editor


  • بچے کی بار میں Table Editor

    پر جائیںٹابلیس ایڈیٹر


  • For each of the three tables (polls, options, votes):

    • Click the three dots → Edit Table

    • Toggle "Enable Realtime"

    • Save changes


  • تین ٹیبلوں میں سے ہر ایک کے لئے (polls، options، votes):

    pollsoptionsvotes
    • Click the three dots → Edit Table

    • Toggle "Enable Realtime"

    • Save changes


  • تین پوائنٹس پر کلک کریں → Edit Table

  • بچوں پر کلک کریں Edit Table

    دوسرے ٹیبل
  • Toggle "Realtime"

  • Toggle "Realtime کو فعال کریں"

    "Realtime کی اجازت دیتا ہے"
  • Save changes


  • تبدیلیوں کو محفوظ کریں


    App میں Supabase Email Authentication کو نافذ کرنا

    اس ڈیمو ایپ میں، کوئی بھی اپلی کیشن پر دستیاب سروے کی فہرست کو دیکھ سکتا ہے، فعال اور ختم ہونے والے دونوں. ایک سروے کی تفصیلات کو دیکھنے کے لئے، کسی بھی سروے پر انتظام، یا ووٹ کرنے کے لئے، صارف کو لاگ ان ہونا ضروری ہے. ہم اس منصوبے کے لئے تصدیق کے ذریعہ ای میل اور پاس ورڈ کا استعمال کریں گے. آپ کے Next.js پروجیکٹ میں .env.local:

    .env.local
    NEXT_PUBLIC_SUPABASE_URL=your_supabase_url NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key 
    NEXT_PUBLIC_SUPABASE_URL=your_supabase_url NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key


    آپ کے لاگ ان اجزاء کو ای میل / پاس ورڈ کے ذریعے سائن اپ اور لاگ ان دونوں کو منظم کرنے کے لئے اپ ڈیٹ کریں:


    import { useState } from "react"; import { createClient } from "@/utils/supabase/component"; const LogInButton = () => { const supabase = createClient(); async function logIn() { const { error } = await supabase.auth.signUp email({ data: user_name: userName, }, }); if (error) { setError(error.message); } else { setShowModal(false); } } else async function signUp() { const error } { const error } = await supabase.auth.signUp{ email, password options: { data: user_name, } }; if (error) {Error(error.messageimport { useState } from "react";
    import { createClient } from "@/utils/supabase/component";
    
    const LogInButton = () => {
      const supabase = createClient();
    
      async function logIn() {
        const { error } = await supabase.auth.signInWithPassword({
          email,
          password,
        });
        if (error) {
          setError(error.message);
        } else {
          setShowModal(false);
        }
      }
      
      async function signUp() {
        const { error } = await supabase.auth.signUp({
          email,
          password,
          options: {
            data: {
              user_name: userName,
            },
          },
        });
        if (error) {
          setError(error.message);
        } else {
          setShowModal(false);
        }
      }
    
      const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        setError("");
    
        if (isLogin) {
          await logIn();
        } else {
          await signUp();
        }
      };
    
      return (
        <>
          <button
            onClick={() => setShowModal(true)}
            className="flex items-center gap-2 p-2 bg-gray-800 text-white rounded-md">
            Log In
          </button>
          ...
        </>
      );
    };
    
    export default LogInButton;
    


    یہاں، ہم ایک صارف کو لاگ ان کرنے کے لئے Supabase کی signInWithPassword طریقہ کار کا استعمال کرتے ہیں اور signUp طریقہ کار کو اپنے ای میل اور پاس ورڈ کے ساتھ ایک نیا صارف کو لاگ ان کرنے کے لئے استعمال کرتے ہیں.

    ہم صارف کے میٹا ڈیٹا میں user_name میدان میں صارف کا نام بھی ذخیرہ کرتے ہیں.signInWithPasswordsignUpuser_name


    آپ بھی supabase.auth.signOut() استعمال کرسکتے ہیں کہ صارفین کو لاگ ان کریں اور ان کو ہدایت کریں:

    supabase.auth.signOut()


    Import { createClient } from "@/utils/supabase/component"; import { useRouter } from "next/router"; const LogOutButton = ({ closeDropdown }: { closeDropdown: () => void }) => { const router = useRouter(); const supabase = createClient(); const handleLogOut = async () => { await supabase.auth.signOut(); closeDropdown(); router.push("/"}); return ( ... ); } export default LogOutButton; 
    import { createClient } from "@/utils/supabase/component"; import { useRouter } from "next/router"; const LogOutButton = ({ closeDropdown }: { closeDropdown: () => void }) => { const router = useRouter(); const supabase = createClient(); const handleLogOut = async () => { await supabase.auth.signOut(); closeDropdown(); router.push("/"); }; return ( ... ); }; export default LogOutButton;


    یہاں، ہم Supabase سے signOut طریقہ کار کا استعمال کرتے ہیں، صارف کو لاگ ان کرنے اور ان کو ہوم پیج پر ہدایت کرنے کے لئے.

    signOut

    صارف کی تصدیق کی حالت میں تبدیلیوں کے لئے سننے

    صارف کی تصدیق کی حالت میں تبدیلیوں کے لئے سننا ہمیں صارف کی تصدیق کی حالت پر مبنی UI کو اپ ڈیٹ کرنے کی اجازت دیتا ہے.


    • Login/Logout بٹنز جیسے UI عناصر کو دکھائیں / چھپائیں
    • محتمل طور پر محفوظ صفحات (جیسے ووٹنگ یا سروے کا انتظام) تک رسائی کو محدود کریں
    • محتمل صارفین کو صرف محدود کارروائیوں کو انجام دینے کے قابل بنائیں
  • Show/hide UI elements such as login/logout buttons
  • محتمل طور پر محفوظ صفحات تک رسائی کو محدود کریں (مثال کے طور پر ووٹنگ یا سروے کا انتظام کریں)
  • مزید تصدیق شدہ صارفین کو محدود کارروائیوں کو انجام دے سکتے ہیں

  • We will use supabase.auth.onAuthStateChange() to listen to these events and update the app accordingly.

    supabase.auth.onAuthStateChange()


    In the Layout.tsx file: Track Global Auth State

    In میںLayout.tsxfile: ٹریک عالمی Auth State


    import React، { useEffect, useState } سے "react"; import { createClient } سے "@/utils/supabase/component"; import { User } سے "@supabase/supabase-js"; const Layout = ({ بچوں }: { بچوں: React.ReactNode }) => { data = supabase.authon.AuthonStateChange((event, session) => useEffect(() => { const fetchUser = async () => { const supabase = createClient(); { data = supabase.authon.AuthonStateChange((event, session) => { set(Useression?.import React, { useEffect, useState } from "react";
    import { createClient } from "@/utils/supabase/component";
    import { User } from "@supabase/supabase-js";
    
    const Layout = ({ children }: { children: React.ReactNode }) => {
      const [user, setUser] = useState<User | null>(null);
    
      useEffect(() => {
        const fetchUser = async () => {
          const supabase = createClient();
          const { data } = supabase.auth.onAuthStateChange((event, session) => {
            setUser(session?.user || null);
          });
    
          return () => {
            data.subscription.unsubscribe();
          };
        };
    
        fetchUser();
      }, []);
    
      return (
        ...
      );
    };
    
    export default Layout;
    

    مرنے والے صفحات پر رسائی محدود

    جیسے صفحات پر سروے کی تفصیلات یا سروے کے انتظام، آپ کو غیر معتبر صارفین کو ان تک رسائی حاصل کرنے سے روکنے کے لئے تصدیق کی حالت میں تبدیلیوں کے لئے بھی سننا چاہئے.

    پول کی تفصیلاتپرس مینجمنٹ


    اس طرح یہ pages/polls/[id].tsx میں نظر آتا ہے:

    pages/polls/[id].tsx
    Import { createClient } from "@/utils/supabase/component"; import { User } from "@supabase/supabase-js"; const Page = () => { const [user, setUser] = useState<User Átha null> (null); useEffect(() => { const fetchUser = async () => { const supabase = createClient(); const { data } = supabase.auth.onAuthStateChange((انٹ، سیشن) => { setUser(session?.user at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at atimport { createClient } from "@/utils/supabase/component";
    import { User } from "@supabase/supabase-js";
    
    const Page = () => {
      const [user, setUser] = useState<User | null>(null);
    
      useEffect(() => {
        const fetchUser = async () => {
          const supabase = createClient();
          const { data } = supabase.auth.onAuthStateChange((event, session) => {
            setUser(session?.user || null);
            setLoading(false);
          });
    
          return () => {
            data.subscription.unsubscribe();
          };
        };
    
        fetchUser();
      }, []);
    
      return (
        ...
      );
    
    export default Page;
    


    اور ایک اسی طرح کا نمونہ pages/polls/manage.tsx میں لاگو ہوتا ہے، جہاں صارفین کو صرف ان کے اپنے سروے دیکھنا چاہئے جب وہ لاگ ان کر رہے ہیں:

    pages/polls/manage.tsx


    import { createClient } سے "@/utils/supabase/component"; import { User } سے "@supabase/supabase-js"; const Page = () => { const [user, setUser] = useState<User Átha null> const supabase = createClient(); useEffect(() => { const fetchUser = async () => { const { data } = supabase.auth.onAuthStateChangeevent((session, session) => { setUser(session?.user at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at atimport { createClient } from "@/utils/supabase/component";
    import { User } from "@supabase/supabase-js";
    
    const Page = () => {
      const [user, setUser] = useState<User | null>(null);
      
      const supabase = createClient();
    
      useEffect(() => {
        const fetchUser = async () => {
          const { data } = supabase.auth.onAuthStateChange((event, session) => {
            setUser(session?.user || null);
            if (!session?.user) {
              setLoading(false);
            }
          });
    
          return () => {
            data.subscription.unsubscribe();
          };
        };
    
        fetchUser();
      }, []);
    
      return (
        ...
      );
    };
    
    export default Page;
    


    یہ نمونے اس بات کو یقینی بناتے ہیں کہ آپ کا UI صارف کی موجودہ تصدیق کی حالت کا تعین کرتا ہے اور ہم بعد میں شامل کرنے والے تصدیق کی چیک کے لئے بنیاد بناتا ہے. مثال کے طور پر، آپ بعد میں اس user اشیاء کا استعمال کریں گے جب checkPermission Edge Function کو کال کرتے ہیں کہ کیا ایک صارف کو ووٹ کرنے کی اجازت ہے یا ایک مخصوص سروے کا انتظام کرنے کی اجازت ہے.

    usercheckPermission

    پرسنگ اپلی کیشن کی سرگرمیوں کی تعمیر

    Supabase کی ترتیب اور تصدیق کے ساتھ کام کرتے ہوئے، ہم اب سروے ایپ کی بنیادی سرگرمیوں کو تعمیر کرسکتے ہیں.


    • آپ نئے سروے پیدا کریں
    • آپ کے سروے کو حقیقی وقت میں شامل کریں اور دکھائیں
    • ایک ووٹنگ سسٹم کو لاگو کریں
  • آپ کے بارے میں مزید جانیں
  • Fetching and displaying polls in real-time
  • ایک ووٹنگ نظام کا استعمال کریں

  • یہ ہمیں بنیادی اپلی کیشن کے رویے فراہم کرتا ہے جو ہم جلد ہی فوائد کے ساتھ محفوظ کریں گے.

    آپ کے لئے نئے سروے پیدا کریں

    صارفین کو سروے بنانے کے لئے لاگ ان ہونا ضروری ہے. ہر سروے میں ایک سوال، ایک اختتام کی تاریخ، اور ایک سیٹ اختیارات شامل ہیں. ہم یہ بھی ریکارڈ کرتے ہیں کہ سروے کو کس نے پیدا کیا تاکہ ہم بعد میں اس رشتے کو رسائی کنٹرول کے لئے استعمال کرسکتے ہیں.


    NewPoll.tsx کے اندر، تصدیق شدہ صارف کو حاصل کریں، اور Supabase استعمال کرتے ہوئے سروے اور اس کے اختیارات کو داخل کریں:

    NewPoll.tsx


    کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپیimport React, { useEffect, useState } from "react"; import { createClient } from "@/utils/supabase/component"; import { User } from "@supabase/supabase-js"; const NewPoll = () => { const [user, setUser] = useState<User | null>(null); const supabase = createClient(); useEffect(() => { const fetchUser = async () => { const supabase = createClient(); const { data } = supabase.auth.onAuthStateChange((event, session) => { setUser(session?.user || null); }); return () => { data.subscription.unsubscribe(); }; }; fetchUser(); }, []); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (question.trim() && options.filter(opt => opt.trim()).length < 2) { setErrorMessage("Please provide a question and at least two options."); return; } // Create the poll const { data: poll, error: pollError } = await supabase .from("polls") .insert({ question, expires_at: new Date(expiryDate).toISOString(), created_by: user?.id, creator_name: user?.user_metadata?.user_name, }) .select() .single(); if (pollError) { console.error("Error creating poll:", pollError); setErrorMessage(pollError.message); return; } // Create the options const { error: optionsError } = await supabase.from("options").insert( options .filter(opt => opt.trim()) .map(text => ({ poll_id: poll.id, text, })) ); if (!optionsError) { setSuccessMessage("Poll created successfully!"); handleCancel(); } else { console.error("Error creating options:", optionsError); setErrorMessage(optionsError.message); } }; return ( ... ); }; export default NewPoll;

    ہم بعد میں Permit.io میں "Creator" کردار کو تنصیب کرنے کے لئے یہاں ایک Edge Function کال کریں گے.

    پرسوں کو فٹنگ اور دکھانے

    Polls کو active (نہیں ختم) اور past (نہیں ختم) میں تقسیم کیا جاتا ہے. آپ کو موجودہ ٹائم سٹیمپ کی طرف سے فلٹر کیا گیا Supabase سوالات کا استعمال کرتے ہوئے ان کو حاصل کرسکتے ہیں، اور فوری طور پر تبدیلیوں کو ظاہر کرنے کے لئے حقیقی وقت کے دستاویزات کو قائم کرسکتے ہیں.

    فعالپچھلا


    pages/index.tsx سے مثال:

    pages/index.tsx


    ٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭import { PollProps } from "@/helpers"; import { createClient } from "@/utils/supabase/component"; export default function Home() { const supabase = createClient(); useEffect(() => { const fetchPolls = async () => { setLoading(true); const now = new Date().toISOString(); try { // Fetch active polls const { data: activePolls, error: activeError } = await supabase .from("polls") .select( ` id, question, expires_at, creator_name, created_by, votes (count) ` ) .gte("expires_at", now) .order("created_at", { ascending: false }); if (activeError) { console.error("Error fetching active polls:", activeError); return; } // Fetch past polls const { data: expiredPolls, error: pastError } = await supabase .from("polls") .select( ` id, question, expires_at, creator_name, created_by, votes (count) ` ) .lt("expires_at", now) .order("created_at", { ascending: false }); if (pastError) { console.error("Error fetching past polls:", pastError); return; } setCurrentPolls(activePolls); setPastPolls(expiredPolls); } catch (error) { console.error("Unexpected error fetching polls:", error); } finally { setLoading(false); } }; fetchPolls(); // Set up real-time subscription on the polls table: const channel = supabase .channel("polls") .on( "postgres_changes", { event: "*", schema: "public", table: "polls", }, fetchPolls ) .subscribe(); return () => { supabase.removeChannel(channel); }; }, []); return ( ... ); }

    صارف سروے کو دیکھنے اور منظم کرنے

    یہاں، ہم Supabase میں polls ٹیبل سے فعال اور ماضی کے سروے حاصل کر رہے ہیں. ہم بھی polls ٹیبل میں تبدیلیوں کے لئے سننے کے لئے ایک حقیقی وقت کے اختتام کو قائم کر رہے ہیں تاکہ ہم تازہ ترین سروے کے اعداد و شمار کے ساتھ UI کو اپ ڈیٹ کرسکتے ہیں۔ فعال اور ماضی کے سروے کے درمیان فرق کرنے کے لئے، ہم ہر سروے کے ختم ہونے کی تاریخ کو موجودہ تاریخ کے ساتھ موازنہ کر رہے ہیں.

    pollspolls


    pages/manage.tsx صفحے کو اپ ڈیٹ کریں اور صرف صارف کی طرف سے پیدا کردہ سروے کو تلاش کریں:

    pages/manage.tsx


    import { PollProps } سے "@/helpers"; const Page = () => { useEffect(() => { if (!user?.id) return; const fetchPolls = async () => { try { const_at", { ascending: error } = await supabase .from("polls") .select( `id, question, expires_at, creator_name, created_by, votes (count) `) .eq("created_by", user.id) .order("created_at", { ascending: error }); if (error) default consoleerror("Error fet polls:", error); return; } setPolls filter(data return schol.de [=import { PollProps } from "@/helpers";
    
    const Page = () => {
      
      useEffect(() => {
        if (!user?.id) return;
    
        const fetchPolls = async () => {
          try {
            const { data, error } = await supabase
              .from("polls")
              .select(
                `
                id,
                question,
                expires_at,
                creator_name,
                created_by,
                votes (count)
              `
              )
              .eq("created_by", user.id)
              .order("created_at", { ascending: false });
    
            if (error) {
              console.error("Error fetching polls:", error);
              return;
            }
    
            setPolls(data || []);
          } catch (error) {
            console.error("Unexpected error fetching polls:", error);
          } finally {
            setLoading(false);
          }
        };
    
        fetchPolls();
    
        // Set up real-time subscription
        const channel = supabase
          .channel(`polls_${user.id}`)
          .on(
            "postgres_changes",
            {
              event: "*",
              schema: "public",
              table: "polls",
              filter: `created_by=eq.${user.id}`,
            },
            fetchPolls
          )
          .subscribe();
    
        return () => {
          supabase.removeChannel(channel);
        };
      }, [user]);
    
       return (
        ...
      );
    };
    
    export default Page;
    


    یہاں، ہم صرف صارف کی طرف سے تخلیق کردہ سروے حاصل کرتے ہیں اور polls ٹیبل میں حقیقی وقت کے اپ ڈیٹس کو سنتے ہیں تاکہ UI تازہ ترین سروے کے اعداد و شمار کے ساتھ اپ ڈیٹ کیا جاتا ہے.

    polls


    اس کے علاوہ، PollCard اجزاء کو اپ ڈیٹ کریں تاکہ اگر ایک لاگ ان شدہ صارف سروے کی تخلیق کرنے والا ہے تو، سروے کو ترمیم کرنے اور حذف کرنے کے لئے آئکنوں کو سروے میں دکھایا جائے گا.

    PollCard


    import { createClient} سے "@/utils/supabase/component"; import { User } سے "@supabase/supabase-js"; const PollCard = ({ poll }: { poll: PollProps }) => { const data } = supabase.auth.onAuthStateChangeevent(( session, session) => { setUser(session.user. قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدمimport { createClient } from "@/utils/supabase/component";
    import { User } from "@supabase/supabase-js";
    
    const PollCard = ({ poll }: { poll: PollProps }) => {
      const [user, setUser] = useState<User | null>(null);
      
      useEffect(() => {
        const supabase = createClient();
        const fetchUser = async () => {
          const { data } = supabase.auth.onAuthStateChange((event, session) => {
            setUser(session?.user || null);
            setLoading(false);
          });
    
          return () => {
            data.subscription.unsubscribe();
          };
        };
    
        fetchUser();
      }, []);
    
      return (
        ...
          )}
        </Link>
      );
    };
    
    export default PollCard;
    


    تو اب، ایک سروے کارڈ پر، اگر لاگ ان کردہ صارف سروے کی تخلیق کرنے والا ہے تو، سروے کو ترمیم اور حذف کرنے کے لئے آئکنز ان کو دکھایا جائے گا.

    پرسٹ ووٹنگ کے نظام کو لاگو کرنے

    پرسٹنگ کی منطق کے مطابق:

    • ایک صارف پر صرف ایک ووٹ
    • Creators cannot vote on their own polls
    • Votes are stored in the votes table
    • Results are displayed and updated in real time
  • ایک صارف پر صرف ایک ووٹ
  • Creators cannot vote on their own polls
  • مقالات کو votes ٹیبل میں ذخیرہ کیا جاتا ہے
  • votes
  • تعدادات واقعی وقت میں دکھایا جاتا ہے اور اپ ڈیٹ کیا جاتا ہے

  • ہمارا خیال ہے کہ ViewPoll.tsx اجزاء میں یہ کیسے کام کرتا ہے:

    ViewPoll.tsx


    Logged-In User کو فٹ کریںWe need the current user’s ID to determine voting eligibility and record their vote.

    Fetch the Logged-In User پر کلک کریں


    Import { createClient } from "@/utils/supabase/component"; import { User } from "@supabase/supabase-js"; const ViewPoll = () => { const [user, setUser] = useState<User Átha null>(null); const supabase = createClient(); useEffect(() const fetchUser = async () => { const data: { user }, } = await supabase.auth.getUser(); setUser(user); }; fetchUser(); }, []; </>Pre>import { createClient } from "@/utils/supabase/component";
    import { User } from "@supabase/supabase-js";
    
    const ViewPoll = () => {
      const [user, setUser] = useState<User | null>(null);
    
      const supabase = createClient();
    
      useEffect(() 
        const fetchUser = async () => {
          const {
            data: { user },
          } = await supabase.auth.getUser();
          setUser(user);
        };
    
        fetchUser();
      }, []);
    


    Load Poll Details and Check Voting Statusایک بار جب ہم صارف کو حاصل کرتے ہیں، ہم حاصل کرتے ہیں:

    Load Poll Details and Check Voting Status
    • پرسٹ خود (مقابلہ اختیارات اور ووٹ کا حساب بھی شامل ہے)
    • اگر اس صارف نے پہلے ہی ووٹ دیا ہے
  • پرسٹ خود (ایکشنز اور ووٹ کی تعداد سمیت)
  • یا اس صارف نے پہلے ہی ووٹ دیا ہے؟

  • We also call these again later in real-time updates.


     useEffect(() => { اگر (!user) { return; } const checkUserVote = async () => { const { data: votes } = await supabase .from("votes") .select("id") .eq("poll_id", query.id) .eq("user_id", user.id) .single(); setHasVoted(!!votes); setVoteLoading(false); }; constchPoll = async () => { const} data = await supabase .from("polls", query.id) .eq(options, *, id, text, votes (count) ) ` ) .eq("quid", query.  useEffect(() => {
        if (!user) {
          return;
        }
        
        const checkUserVote = async () => {
          const { data: votes } = await supabase
            .from("votes")
            .select("id")
            .eq("poll_id", query.id)
            .eq("user_id", user.id)
            .single();
    
          setHasVoted(!!votes);
          setVoteLoading(false);
        };
       
        const fetchPoll = async () => {
          const { data } = await supabase
            .from("polls")
            .select(
              `
              *,
              options (
                id,
                text,
                votes (count)
              )
            `
            )
            .eq("id", query.id)
            .single();
    
          setPoll(data);
          setPollLoading(false);
    
          checkUserVote();
        };
    
        fetchPoll();
    


    Real-time اپ ڈیٹس کے لئے سنیں

    Real-time اپ ڈیٹس کے لئے سنیں

    We subscribe to changes in the votes table, scope to this poll.When a new vote is cast, we retrieve updated poll data and voting status.

    votes


     const channel = supabase .channel(`poll-${query.id}`) .on( "postgres_changes", { event: "*", schema: "public", table: "votes", filter: `poll_id=eq.${query.id}`, }, () => { fetchPoll(); checkUserVote(); } ) .subscribe(); return () => { supabase.removeChannel(channel); }; }, [query.id, user]); 
    const channel = supabase .channel(`poll-${query.id}`) .on( "postgres_changes", { event: "*", schema: "public", table: "votes", filter: `poll_id=eq.${query.id}`, }, () => { fetchPoll(); checkUserVote(); } ) .subscribe(); return () => { supabase.removeChannel(channel); }; }, [query.id, user]);


    آپ کی رائے کا اظہار کریں

    آپ کی رائے کا اظہار کریں

    اگر صارف نے ووٹ نہیں کیا ہے اور ووٹ کرنے کی اجازت ہے (ہم بعد میں اجازت چیک شامل کریں گے)، ہم ان کی ووٹ شامل کریں گے.


     const handleVote = async (optionId: string) => { اگر (!user) واپسی؛ چلو { const { error } = await supabase.from("votes").insert({ poll_id: query.id, option_id: optionId, user_id: user.id, }); اگر (!error) { setHasVoted(true); } } catch (error) { console.error("Error voting:", error); }؛ 
    const handleVote = async (optionId: string) => { if (!user) return; try { const { error } = await supabase.from("votes").insert({ poll_id: query.id, option_id: optionId, user_id: user.id, }); if (!error) { setHasVoted(true); } } catch (error) { console.error("Error voting:", error); } };


    پرس کے نتائج کو دکھائیںہم نے تمام ووٹوں کی کل تعداد اور ختم ہونے کا وقت پر ایک بونس کا حساب کیا.

    آپ اس کے بعد ترقی کے بارز یا اعداد و شمار کو دکھانے کے لئے اس کا استعمال کرسکتے ہیں.


    Poll Results دکھائیں


     اگر (!pollintza-poll.poll.poll.poll.poll.poll.poll.poll.poll.poll.poll.poll.poll.poll.poll.poll.  if (!poll || pollLoading || voteLoading) return <div>Loading...</div>;
    
      // 6. calculate total votes
      const totalVotes = calculateTotalVotes(poll.options);
      const countdown = getCountdown(poll.expires_at);
    
      return (
      ...
      );
    };
    
    export default ViewPoll;
    


    اس ترتیبات کے ساتھ، آپ کا ووٹنگ سسٹم مکمل طور پر کام کرتا ہے. لیکن اب، جو بھی لاگ ان کرسکتے ہیں، تکنیکی طور پر ووٹ کرنے کی کوشش کرسکتے ہیں - یہاں تک کہ ان کے اپنے سروے پر.کی اجازت کی جانچ پڑتالآپ کی اجازتSupabase Edge Functions


    ہم ایسا کرنے سے پہلے، ہم سب سے پہلے اس قسم کی اجازت کی سطح پر نظر ڈالیں جو ہم انسٹال کرنے جا رہے ہیں.

    Relationship-Based Access Control (RBAC) کو سمجھنا

    Supabase تصدیق اور بنیادی رینج کی سطح کی اجازتیں اچھی طرح سے کام کرتا ہے، لیکن اس طرح کے پیچیدہ قوانین کی حمایت نہیں کرتا:

    • آپ کے صارفین کو ان کے اپنے سروے پر ووٹ دینے سے روکنے
    • ایک وسائل کے مطابق کرداروں (مثال کے طور پر ایک مخصوص سروے کے لئے "Creator")
    • آپ کی بیرونی پالیسیوں کے ذریعے رسائی کا انتظام
  • صارفین کو اپنے سروے پر ووٹ دینے سے روکنے
  • ہر وسائل کے لئے کرداروں کا تعین کریں (مثال کے طور پر "Creator" ایک مخصوص سروے کے لئے)
  • جاندار پالیسیوں کے ذریعے رسائی کا انتظام

  • اس طرح کے رشتے پر مبنی اجازتوں کی حمایت کرنے کے لئے، ہم Permit.io کے ساتھ ReBAC کو انسٹال کریں گے.


    Relationship-Based Access Control (ReBAC) is a model for managing permissions based on the relationships between users and resources. Instead of relying solely on roles or attributes (as in RBAC or ABAC), ReBAC determines access by evaluating how a user is connected to the resource they’re trying to access.

    Relationship-Based Access Control (ReBAC)Relationship-Based Access Control (ReBAC)


    اس ٹیوٹوریل میں، ہم ایک ووٹنگ ایپلی کیشن پر ReBAC کو لاگو کرتے ہیں:

    • A user who created a poll is the only one who can manage (edit/delete) it
    • A user cannot vote on their own poll
    • Other authenticated users can vote once per poll
  • A user who created a poll is the only one who can manage (edit/delete) it
  • پیدا کیا گیا
  • A user cannot vote on their own poll
  • cannot نہیں کر سکتےOwn کے بارے میں
  • ایک بار ہر سروے پر دوسرے قابل اعتماد صارفین کو ووٹ دیا جا سکتا ہے

  • Permit.io میں ان تعلقات کی ماڈلنگ کے ذریعہ، ہم فائدہ مند رسائی کے قوانین کو مقرر کرسکتے ہیں جو Supabase کے داخلہ ریل سطح سیکورٹی (RLS) سے زیادہ ہیں.

    ہم Supabase Edge Functions اور Permit کی پالیسی کے انجن کا استعمال کرتے ہوئے ان کو چلانے کے وقت لاگو کریں گے.



    For more on ReBAC, check out Permit.io’s ReBAC docs.

    Permit.io’s ReBAC docs

    ایکشن کنٹرول ڈیزائن

    ہمارے Polling اپلی کیشن کے لئے، ہم مقرر کریں گے:

    • One resource with resource-specific actions:
      • polls: create, read, delete, update.
    • Two roles for granting permission levels based on a user's relationship with the resources:
      • authenticated: Can perform create and read actions in polls. Can not delete in polls, or update actions in polls. Can
      • creator: CancodeCreate
      • ایک ذریعہ جس میں وسائل کی مخصوص کارروائی ہوتی ہے:
        • polls: create، read، delete، update.
        • polls: create، read، delete، update.

        polls: create، read، delete، update.پولزcreatereaddeleteupdate

      • :
        • authenticated: create and read actions in polls. Can not delete, or update actions in polls.
        • creator: Can create, read, delete, and update actions in polls. Can perform read and create actions in votes. Can not use create on their own polls.
      • ٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭
      • authenticated: create اور read کارروائیوں کو سروے میں انجام دے سکتا ہے. delete یا update کارروائیوں کو سروے میں انجام دے سکتا ہے.
      • تصویری:createreaddeleteupdateاس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہCreator: کے بارے میںcreatereaddeleteupdatereadcreatecreate

        Permit.io کو ترتیب دیں

        آپ کی اجازت میں اجازت کے ماڈل کی ترتیبات کے ذریعے چلتے ہیں.

        • Create a new project in Permit.io
          • Name it something like supabase-polling
        • Define the polls resource
          • Go to the Policy → Resources tab
          • Click “Create Resource”
          • Name it polls, and add the actions: read, create, update, delete
        • Enable ReBAC for the resource
          • Under “ReBAC Options,” define the following roles:

            • authenticated
            • creator
          • Click Save


      • Create a new project in Permit.io
        • Name it something like supabase-polling
      • Create a new projectCreate a new project in Permit.io
        • ایک ایسی چیز کا نام کریں جیسے supabase-polling
      • ایک ایسی چیز کا نام کریں جیسے supabase-polling
      • supabase-polling polls resource
        • Policy → Resources tab
        • Click “Create Resource”
        • Name it polls، اور اقدامات شامل کریں: read، create، update، delete
    • تصویر کریںpollsمقاصد
    • Policy → Resources tab
    • Click “Create Resource”
    • Name it polls، اور اقدامات شامل کریں: read، create، update، delete
  • Go to Policy → Resources tab
  • پولیس → وسائل
  • Click “Create Resource”
  • “Create Resource”
  • Name it polls، اور اقدامات شامل کریں: read، create، update، delete
  • pollsreadcreateupdatedelete
  • مقصد کے لئے ReBAC کو فعال کریں
    • مقصد کے اختیارات کے تحت، مندرجہ ذیل کردار ادا کریں:

      • authenticated
      • creator
  • Click Save


    Resource کے لئے ReBAC کو فعال کریں
    • Rebac اختیارات کے تحت، مندرجہ ذیل کردار ادا کریں:

      • creator
    • Click Save


  • Rebac اختیارات کے تحت، مندرجہ ذیل کردار ادا کریں:

    • authenticated
    • creator
  • “ReBAC اختیارات” کے تحت، مندرجہ ذیل کردار ادا کریں:

  • تصویری
  • authenticated
  • creator
  • creator

    Click Save


    Click Save

    پر کلک کریں محفوظ کریں


    آپ نے صرف پیدا کردہ وسائل سے رولز کو دیکھنے کے لئے "لڑکیوں" ٹیب پر پلگ ان کریں. یاد رکھیں کہ اجازت اس ہدایات (admin، editor، user) کو پیدا کیا ہے جو اس ہدایات کے لئے غیر ضروری ہیں.

    admineditoruser


    • Define access policies

      • Go to the Policy → Policies tab
      • Use the visual matrix to define:
        • authenticated can read and create polls

        • creator can read, update, and delete polls

        • (Optional) You can configure vote permissions as part of this or via a second resource if you model votes separately



    • Add resource instances

      • Go to Directory → Instances

      • Add individual poll IDs as resource instances (you’ll automate this later when new polls are created)

      • Assign roles to users per poll (e.g. user123 is creator of poll456)


  • Define access policies

    • Go to the Policy → Policies tab
    • Use the visual matrix to define:
      • authenticated can read and create polls

      • creator can read, update, and delete polls

      • (Optional) You can configure vote permissions as part of this or via a second resource if you model votes separately



  • آپ کی رسائی کی پالیسی کا تعین کریں

    آپ کی رسائی کی پالیسی کا تعین کریں
    • > Policy → Policies tab
    • authenticated read اور create polls

    • creator read، update، اور delete polls

    • (مختصر) آپ کو اس کے حصہ کے طور پر یا ایک دوسرا وسائل کے ذریعے ووٹنگ کی اجازتیں ترتیب دے سکتے ہیں اگر آپ الگ الگ الگ ووٹنگ


  • Go to Policy → پالیسییں tab
  • پولیس → پالیسییں
  • تصویر کا استعمال کریں:
    • authenticated can read and create polls

    • creator can read, update, and delete polls

    • (مختصر) آپ اس کے حصہ کے طور پر یا ایک دوسرا وسائل کے ذریعہ ووٹنگ کی اجازتیں ترتیب دے سکتے ہیں اگر آپ ووٹنگ کو منفرد طور پر ماڈل کریں


    • authenticated کر سکتے ہیں read اور create polls

    • creator کر سکتے ہیں read, update, اور delete polls

    • (مختصر) آپ کو اس کے حصہ کے طور پر یا ایک دوسری وسائل کے ذریعے ووٹنگ کی اجازتیں ترتیب دے سکتے ہیں اگر آپ الگ الگ ہی طرح کا ووٹنگ کر رہے ہیں


  • authenticated کر سکتے ہیں read اور create polls

  • authenticated کر سکتے ہیں read اور create polls

    authenticatedreadcreate
  • creator read، update، اور delete polls

  • creator کر سکتے ہیں read، update، اور delete polls

    creatorreadupdatedelete
  • (مختصر) آپ اس کے حصے کے طور پر یا دوسری وسائل کے ذریعے ووٹ کی اجازتیں ترتیب دے سکتے ہیں اگر آپ ووٹ کو منفرد طور پر ماڈل کریں


  • (مختصر) آپ اس کے حصہ کے طور پر یا دوسری وسائل کے ذریعے ووٹ کی اجازتیں ترتیب دے سکتے ہیں اگر آپ ووٹ کو منفرد طور پر ماڈل کرتے ہیں



    • Directory → Instances

    • مختلف سروے ایڈز کو سروے ایڈز کے طور پر شامل کریں (آپ نئے سروے پیدا ہونے کے بعد اس کو خود کار طریقے سے کرسکتے ہیں)


    • ایک سروے پر صارفین کو کردار ادا کریں (مثلا user123 creator کے poll456)


  • مقالات شامل کریں

    مقالات شامل کریں
    • ڈائریکٹری → انسٹینز

    • ایک ذاتی سروے ایڈز کو وسائل کے انسٹینز کے طور پر شامل کریں (آپ نئے سروے پیدا ہونے کے بعد اس کو خود کار طریقے سے کرسکتے ہیں)

    • ایک سروے پر صارفین کو کردار ادا کریں (مثال کے طور پر user123 creator ہے poll456)


  • ڈائریکٹری میں جائیں → انسٹینز

  • ڈائریکٹری میں جائیں → Instances

    ڈائریکٹری → انٹرفیسز
  • نوعی سروے ایڈز کو وسائل کے انسٹال کے طور پر شامل کریں (آپ نئے سروے پیدا ہونے کے بعد اس کو خود کار طریقے سے کریں گے)

  • نوعی سروے ایڈز کو وسائل کے انسٹال کے طور پر شامل کریں (آپ نئے سروے پیدا ہونے کے بعد اس کو خود کار طریقے سے کرسکتے ہیں)

  • ایک سروے پر صارفین کو کردار ادا کریں (مثال کے طور پر user123 creator ہے poll456)


  • ایک سروے پر صارفین کو کردار ادا کریں (مثال کے طور پر user123 creator کے poll456)

    user123creatorpoll456


    اس ساخت نے ہمیں فکسڈ رسائی کے قوانین کو لکھنے اور ان کو ہر صارف، ہر سروے پر لاگو کرنے کی صلاحیت دی ہے۔


    Now that we have completed the initial setup on the Permit dashboard, let's use it in our application. Next, we’ll connect Permit.io to our Supabase project via Edge Functions that:

    Permit.io
    • نئی صارفین کو سنک کریں
    • Creator roles کا تعین کریں
    • Check access on demand
  • Sync نئے صارفین
  • Creator Roles کا تعین کریں
  • استعمال کی درخواست پر چیک کریں
  • پولنگ ایپلی کیشن میں اجازت مقرر کرنا

    Polling Application میں Permit کی ترتیبات

    Permit offers multiple ways to integrate with your application, but we'll use the Container PDP for this tutorial. You have to host the container online to access it in Supabase Edge functions. You can use services like railway.com. Once you have hosted it, save the url for your container.

    railway.com


    آپ کی اجازت API کلید حاصل کرنے کے لۓ اجازت ڈسپلے بیل میں "Projects" پر کلک کریں، آپ کے کام کر رہے ہیں کہ منصوبے پر پلگ ان کریں، تین پوائنٹس پر کلک کریں، اور "Copy API Key" کا انتخاب کریں.


    آپوریشن کے لئے Supabase Edge Function API کی تخلیق

    Supabase Edge Functions تیسری پارٹی کی خدمات جیسے Permit.io کو منسلک کرنے کے لئے بہترین ہیں.

    ہم ان کا استعمال کریں گے کہ صارفین کو سروے پر مخصوص کارروائیوں کو انجام دینے کی اجازت ہے.


    Supabase Edge Functions

    Supabase میں افعال پیدا کریں

    Supabase میں فائلوں کا تخلیق

    اپنے منصوبے میں Supabase کو ابتدائی کریں اور supabase کے افعال نئے کمانڈ کا استعمال کرتے ہوئے تین مختلف افعال پیدا کریں.supabase functions new

    npx supabase init npx supabase Functions new syncUser npx supabase Functions new updateCreatorRole npx supabase Functions new checkPermission 
    npx supabase init npx supabase functions new syncUser npx supabase functions new updateCreatorRole npx supabase functions new checkPermission

    یہ ایک Functions فارم پیدا کرے گا supabase فارم کے ساتھ ساتھ آخر نقطہ. اب، ہم ہر آخر نقطہ کے لئے کوڈ لکھیں.

    functionssupabase

    Syncing Users to Permit.io on Signup (syncUser.ts)

    syncUser.ts

    یہ فورم Supabase کے SIGNED_UP auth واقعے کے لئے سنتا ہے۔ جب ایک نیا صارف سائن اپ کرتا ہے تو ہم ان کی شناخت کو Permit.io میں سائن اپ کرتے ہیں اور ان کو معاوضہ authenticated کردار فراہم کرتے ہیں.

    SIGNED_UPauthenticated


    ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪import "jsr:@supabase/functions-js/edge-runtime.d.ts"; import { Permit } from "npm:permitio"; const corsHeaders = { 'Access-Control-Allow-Origin': "*", 'Access-Control-Allow-Headers': 'Authorization, x-client-info, apikey, Content-Type', 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT, DELETE', } // Supabase Edge Function to sync new users with Permit.io Deno.serve(async (req) => { const permit = new Permit({ token: Deno.env.get("PERMIT_API_KEY"), pdp: "<https://real-time-polling-app-production.up.railway.app>", }); try { const { event, user } = await req.json(); // Only proceed if the event type is "SIGNED_UP" if (event === "SIGNED_UP" && user) { const newUser = { key: user.id, email: user.email, name: user.user_metadata?.name || "Someone", }; // Sync the user to Permit.io await permit.api.createUser(newUser); await permit.api.assignRole({ role: "authenticated", tenant: "default", user: user.id, }); console.log(`User ${user.email} synced to Permit.io successfully.`); } // Return success response return new Response( JSON.stringify({ message: "User synced successfully!" }), { status: 200, headers: corsHeaders }, ); } catch (error) { console.error("Error syncing user to Permit: ", error); return new Response( JSON.stringify({ message: "Error syncing user to Permit.", "error": error }), { status: 500, headers: { "Content-Type": "application/json" } }, ); } });

    Creator Role کا تعین (updateCreatorRole.ts)

    updateCreatorRole.ts

    ایک بار جب ایک صارف نے ایک سروے تخلیق کی ہے تو، اس تقریب کو کہا جاتا ہے:

    کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی
  • پرسٹ کو ایک نیا Permit.io وسائل انٹرفیس کے طور پر سائن اپ کریں

  • پرسٹ کو ایک نیا Permit.io وسائل انٹرفیس کے طور پر سائن اپ کریں

    ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪

    ایک صارف کو اس سروے کے لئے creator کردار کا تعین کریں

    creator


    ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪import "jsr:@supabase/functions-js/edge-runtime.d.ts"; import { Permit } from "npm:permitio"; const corsHeaders = { 'Access-Control-Allow-Origin': "*", 'Access-Control-Allow-Headers': 'Authorization, x-client-info, apikey, Content-Type', 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT, DELETE', } Deno.serve(async (req) => { const permit = new Permit({ token: Deno.env.get("PERMIT_API_KEY"), pdp: "<https://real-time-polling-app-production.up.railway.app>", }); try { const { userId, pollId } = await req.json(); // Validate input parameters if (!userId || !pollId) { return new Response( JSON.stringify({ error: "Missing required parameters." }), { status: 400, headers: { "Content-Type": "application/json" } }, ); } // Sync the resource (poll) to Permit.io await permit.api.syncResource({ type: "polls", key: pollId, tenant: "default", attributes: { createdBy: userId } }); // Assign the creator role to the user for this specific poll await permit.api.assignRole({ role: "creator", tenant: "default", user: userId, resource: { type: "polls", key: pollId, } }); return new Response( JSON.stringify({ message: "Creator role assigned successfully", success: true }), { status: 200, headers: corsHeaders }, ); } catch (error) { console.error("Error assigning creator role: ", error); return new Response( JSON.stringify({ message: "Error occurred while assigning creator role.", error: error }), { status: 500, headers: { "Content-Type": "application/json" } }, ); } });


    چیک کرنے کی اجازتیں (checkPermission.ts)

    checkPermission.ts

    یہ فہرست گٹیکر کے طور پر کام کرتا ہے - یہ چیک کرتا ہے کہ کیا ایک صارف کو ایک مخصوص سروے پر ایک مخصوص کارروائی (create، read، update، delete) کرنے کی اجازت ہے.

    createreadupdatedelete


    اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہimport "jsr:@supabase/functions-js/edge-runtime.d.ts"; import { Permit } from "npm:permitio"; const corsHeaders = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Authorization, x-client-info, apikey, Content-Type", "Access-Control-Allow-Methods": "POST, GET, OPTIONS, PUT, DELETE", }; Deno.serve(async req => { const permit = new Permit({ token: Deno.env.get("PERMIT_API_KEY"), pdp: "<https://real-time-polling-app-production.up.railway.app>", }); try { const { userId, operation, key } = await req.json(); // Validate input parameters if (!userId || !operation || !key) { return new Response( JSON.stringify({ error: "Missing required parameters." }), { status: 400, headers: { "Content-Type": "application/json" } } ); } // Check permissions using Permit's ReBAC const permitted = await permit.check(userId, operation, { type: "polls", key, tenant: "default", // Include any additional attributes that Permit needs for relationship checking attributes: { createdBy: userId, // This will be used in Permit's policy rules }, }); return new Response(JSON.stringify({ permitted }), { status: 200, headers: corsHeaders, }); } catch (error) { console.error("Error checking user permission: ", error); return new Response( JSON.stringify({ message: "Error occurred while checking user permission.", error: error, }), { status: 500, headers: { "Content-Type": "application/json" } } ); } });

    ملکی ٹیسٹ

    اپنے Supabase dev سرور کو مقامی طور پر کاموں کی جانچ پڑتال کرنے کے لئے شروع کریں:

    npx supabase start npx supabase functions serve 
    npx supabase start npx supabase functions serve

    پھر آپ اپنے افعال پر کلک کرسکتے ہیں:

    <http://localhost:54321/functions/v1/><function-name> 
    <http://localhost:54321/functions/v1/><function-name>

    مثال کے لئے:

    <http://localhost:54321/functions/v1/checkPermission> 
    <http://localhost:54321/functions/v1/checkPermission>

    UI میں لائسنس چیکز کو شامل کریں

    ابھی کہ ہم نے Permit.io کے ساتھ ہماری ذمہ داری منطق تخلیق کی ہے اور Supabase Edge Functions کے ذریعے اسے ظاہر کیا ہے، یہ اپلی کیشن کے اجزاء کے اندر ان چیکوں کو لاگو کرنے کا وقت ہے.


    اس سیکشن میں، ہم ان افعال کو کال کرنے کے لئے اہم UI اجزاء کو اپ ڈیٹ کریں گے اور شرط سے صارف کے کارروائیوں کو اجازت دیں یا بلاک کریں گے جیسے ووٹنگ یا اجازت چیک پر مبنی سروے کا انتظام کریں گے.

    NewPoll.tsx: Poll Creation کے بعد Creator Role Assign

    NewPoll.tsx

    ایک سروے تخلیق کرنے اور اسے Supabase میں محفوظ کرنے کے بعد، ہم updateCreatorRole افعال کو دعوت دیتے ہیں:

    updateCreatorRole‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪
  • Permit.io میں نئے سروے کو ایک وسائل کے طور پر سائن اپ کریں

  • Permit.io میں نئے سروے کو ایک وسائل کے طور پر سائن اپ کریں

    ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪

    ایک مخصوص سروے کے لئے موجودہ صارف کو creator کردار کا تعین کریں

    creator


    ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪:‬‬ ‫‪const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (question.trim() && options.filter(opt => opt.trim()).length < 2) { setErrorMessage("Please provide a question and at least two options."); return; } try { // Create the poll const { data: poll, error: pollError } = await supabase .from("polls") .insert({ question, expires_at: new Date(expiryDate).toISOString(), created_by: user?.id, creator_name: user?.user_metadata?.user_name, }) .select() .single(); if (pollError) { console.error("Error creating poll:", pollError); setErrorMessage(pollError.message); return; } // Create the options const { error: optionsError } = await supabase.from("options").insert( options .filter(opt => opt.trim()) .map(text => ({ poll_id: poll.id, text, })) ); if (optionsError) { console.error("Error creating options:", optionsError); setErrorMessage(optionsError.message); return; } // Update the creator role in Permit.io const response = await fetch( "<http://127.0.0.1:54321/functions/v1//updateCreatorRole>", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ userId: user?.id, pollId: poll.id, }), } ); const { success, error } = await response.json(); if (!success) { console.error("Error updating creator role:", error); // Note: We don't set an error message here as the poll was still created successfully } setSuccessMessage("Poll created successfully!"); handleCancel(); } catch (error) { console.error("Error in poll creation process:", error); setErrorMessage("An unexpected error occurred while creating the poll."); } };

    ViewPoll.tsx: لائسنس کی بنیاد پر ووٹنگ کو محدود کریں

    ViewPoll.tsx

    ایک صارف کو ایک سروے پر ووٹ کرنے کی اجازت دینے سے پہلے، ہم checkPermission تقریب کو فون کرتے ہیں تاکہ اس بات کو یقینی بنائیں کہ وہ create کی اجازت ہے votes وسائل پر.checkPermissioncreatevotes "ایک تخلیقکار اپنے سروے پر ووٹ نہیں کر سکتا."


    مقالات کا جائزہ لیں:

    پرسٹ کرنے کی اجازت چیک کریں:


    const [canVote, setCanVote] = useState(false); useEffect(() => {const checkPermission = async () => { اگر (!user Mediateca!query.id) واپسی; try {const response = await fetch("<http://127.0.1:54321/functions/v1/checkPermission>", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ userId: user.id, operation: "create", key: query.id, }), } {constated = await response.json(); CanVoteVote(permittedconst [canVote, setCanVote] = useState(false);
    
    useEffect(() => {
      const checkPermission = async () => {
        if (!user || !query.id) return;
    
        try {
          const response = await fetch("<http://127.0.0.1:54321/functions/v1/checkPermission>", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify({
              userId: user.id,
              operation: "create",
              key: query.id,
            }),
          });
    
          const { permitted } = await response.json();
          setCanVote(permitted);
        } catch (error) {
          console.error("Error checking permission:", error);
          setCanVote(false);
        }
      };
    
      checkPermission();
    }, [user, query.id]);
    


    اگر صارف کی اجازت نہیں ہے تو ووٹ بٹن غیر فعال کریں:

    اگر صارف کی اجازت نہیں ہے تو ووٹ بٹن غیر فعال کریں:


    <button onClick={() => handleVote(option.id)} disabled={!user Mediateca !canVote}} className="w-full text-left p-4 rounded-md hover:bg-slate-100 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"> {option.text} </button> 
    <button onClick={() => handleVote(option.id)} disabled={!user || !canVote}} className="w-full text-left p-4 rounded-md hover:bg-slate-100 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"> {option.text} </button>


    اگر صارف کو ووٹ کرنے کی اجازت نہیں ہے تو ایک پیغام دکھائیں:

    اگر صارف کو ووٹ کرنے کی اجازت نہیں ہے تو ایک پیغام دکھائیں:


    {user && !canVote && ( <p className="mt-4 text-gray-600">آپ اپنے ووٹ پر ووٹ نہیں کر سکتے</p> )} 
    {user && !canVote && ( <p className="mt-4 text-gray-600">You cannot vote on your own poll</p> )}

    PollCard.tsx: Control Access to Edit/Delete

    PollCard.tsx

    ہم نے بھی update یا delete کی اجازت اس سروے پر موجود ہے یا نہیں کی جانچ پڑتال کرکے سروے کے انتظام کے اقدامات کو محدود کر دیا ہے.

    updatedelete


    آپ کے انتظام کی اجازتیں چیک کریں:

    استعمال کی اجازتوں کی جانچ پڑتال کریں:


    const [canManagePoll, setCanManagePoll] = useState(false); useEffect(() => {const checkPollPermissions = async () => { اگر (!user-language-typescript!poll.id) واپسی؛ چیک کریں { // دونوں edit اور delete permissions constedit [Response, deleteResponse] کے لئے چیک کریں، جسم: JSON.strifingy([f] userId: edit.id، operation: "http://127.0.1:54321/functions/v1/checkPermission>", { method: "POST", headers: {"Content-Type": "Application/json", body: JSON.const [canManagePoll, setCanManagePoll] = useState(false);
    
    useEffect(() => {
      const checkPollPermissions = async () => {
        if (!user || !poll.id) return;
    
        try {
          // Check for both edit and delete permissions
          const [editResponse, deleteResponse] = await Promise.all([
            fetch("<http://127.0.0.1:54321/functions/v1/checkPermission>", {
              method: "POST",
              headers: {
                "Content-Type": "application/json",
              },
              body: JSON.stringify({
                userId: user.id,
                operation: "update",
                key: poll.id,
              }),
            }),
            fetch("/api/checkPermission", {
              method: "POST",
              headers: {
                "Content-Type": "application/json",
              },
              body: JSON.stringify({
                userId: user.id,
                operation: "delete",
                key: poll.id,
              }),
            }),
          ]);
    
          const [{ permitted: canEdit }, { permitted: canDelete }] =
            await Promise.all([editResponse.json(), deleteResponse.json()]);
    
          // User can manage poll if they have either edit or delete permission
          setCanManagePoll(canEdit || canDelete);
        } catch (error) {
          console.error("Error checking permissions:", error);
          setCanManagePoll(false);
        }
      };
    
      checkPollPermissions();
    }, [user, poll.id]);
    


    مطالبہ طور پر انتظام کے بٹن دکھائیں:

    موضوعی طور پر کنٹرول بٹن دکھائیں:


    مزید کریں

    {user?.id === poll?.created_by && ( 
    {user?.id === poll?.created_by && (


    کے ساتھ:

    {canManagePoll && ( <div className="flex justify-start gap-4 mt-4"> <button type="button" onClick={handleEdit}> </button> <button type="button" onClick={handleDelete}> </button> </div> )} 
    {canManagePoll && ( <div className="flex justify-start gap-4 mt-4"> <button type="button" onClick={handleEdit}> </button> <button type="button" onClick={handleDelete}> </button> </div> )}

    مجموعہ کا تجربہ کریں

    ایک بار انضمام، آپ کو ایپ میں مندرجہ ذیل رویے دیکھنا چاہئے:

    • لوگ نکالنے والے صارفین سروے دیکھ سکتے ہیں لیکن بات چیت نہیں کرسکتے

    • آپ didn پیدا کرتے ہوئے سروے پر ووٹ کرسکتے ہیں

    • Creators cannot vote on their own polls

    • Only creators see edit/delete options on their polls


  • لوگ نکالنے والے صارفین سروے دیکھ سکتے ہیں لیکن بات چیت نہیں کرسکتے

  • لوگ نکالنے والے صارفین سروے دیکھ سکتے ہیں لیکن بات چیت نہیں کرسکتے

  • ایٹینٹیج شدہ صارفین ان سروے پر ووٹ کرسکتے ہیں جو وہ didn’t create

  • ایٹینٹیج شدہ صارفین ان سروے پر ووٹ کرسکتے ہیں جو وہ didn't create

    کیا نہیں
  • Creators cannot vote on their own polls

  • Creators cannot vote ان کے اپنے سروے پر

    cannot vote میں نہیں جا سکتا
  • نہیں صرف تخلیق کرنے والوں کو دیکھیں edit/delete اختیارات ان کے سروے


  • ایک ہی تخلیق کار اپنے سروے میں edit/delete اختیارات دیکھتا ہے

    edit/delete کو ہٹا دیں


    آپ کو براؤزر پر جانے کے ذریعے ایپلی کیشن کی تبدیلیوں کو دیکھنے کے قابل ہونا چاہئے۔ ہوم سکرین پر، صارفین کو موجودہ اور گذشتہ سروے کی فہرست دیکھی جا سکتی ہے، چاہے وہ لاگ ان کر رہے ہیں یا نہیں ہیں۔ تاہم، جب وہ ایک سروے پر کلک کرتے ہیں تو وہ سروے کی تفصیلات کو دیکھنے یا اس پر ووٹ نہیں کرسکتے ہیں۔ اس کے بجائے، انہیں لاگ ان کرنے کے لئے کہا جائے گا۔


    ایک بار لاگ ان کرنے کے بعد، صارف نے سروے کی تفصیلات کو دیکھنے اور اس پر ووٹ کر سکتے ہیں. تاہم، اگر صارف نے سروے کا تخلیق کیا ہے تو، وہ اس پر ووٹ نہیں کر سکتے ہیں. وہ ایک پیغام دیکھیں گے جو ان کے اپنے سروے پر ووٹ نہیں کر سکتے ہیں.

    تصویر

    اس ٹیوٹوریل میں، ہم نے ایک حقیقی دنیا میں Next.js ایپلی کیشن میں Supabase تصدیق اور لائسنس کو کیسے لاگو کرنے کا تجربہ کیا.

    Supabase تصدیق اور لائسنسNext.js کے بارے میں

    We started by setting up Supabase Auth for login and signup, created a relational schema with Row Level Security, and added dynamic authorization logic using ReBAC.With the help of Supabase Edge Functions and a Policy Decision Point (PDP), we enforced permission checks directly from the frontend.

    سائپ بیس آؤٹRebac سے رابطہ کریںSupabase Edge FunctionsPolicy Decision Point (PDP)


    مجھے Supabase Auth اور انعطاف پذیر رسائی کنٹرول کے ساتھ مل کر، ہم یہ کر سکتے ہیں:

    سائپ بیس آؤٹ
    • Email اور پاس ورڈ کے ذریعے صارفین کی تصدیق کریں
    • تصدیق شدہ صارفین کے لئے ووٹنگ اور سروے کے انتظام کو محدود کریں
    • Creators from voting on their own polls
    • Assign and evaluate user roles based on relationships to data
  • Email اور پاس ورڈ کے ذریعے صارفین کی تصدیق کریں
  • صارفین کے لئے ووٹنگ اور سروے کے انتظام کو محدود کریں
  • Creators from voting on their own polls روکنے کے لئے
  • اعداد و شمار کے ساتھ تعلقات کی بنیاد پر صارفوں کے کردار کا تعین کریں اور کا جائزہ لیں

  • یہ ترتیبات آپ کو ایپلی کیشنز کی تعمیر کے لئے ایک وسیع پیمانے پر بنیاد فراہم کرتی ہیں جو دونوں تصدیق اور اچھی طرح سے لائسنس کی ضرورت ہوتی ہے.

    مزید پڑھیں

  • Permit.io ReBAC Guide

  • Permit.io ReBAC Guide

    Permit.io ReBAC Guide
  • Permit + Authentication Providers

  • Permit + Authentication Providers

    Permit + Authentication Providers
  • Permit Elements: Embedded UI for Role Management

  • Permit Elements: Embedded UI for Role Management

    Permit Elements: Embedded UI for Role Management
  • Data Filtering with Permit

  • Data Filtering with Permit

    Data Filtering with Permit
  • Audit Logs


  • Audit Logs

    Audit Logs


    Got questions? Join our Slack community, where hundreds of developers are building and discussing authorization.

    Slack communitySlack community

    Trending Topics

    blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks