appwrite / appwrite

Your backend, minus the hassle.
https://appwrite.io
BSD 3-Clause "New" or "Revised" License
43.69k stars 3.91k forks source link

πŸ› Bug Report: app.*****************@service.cloud.appwrite.io (role: applications) missing scope (public) #7881

Closed zain-rajpoot closed 5 months ago

zain-rajpoot commented 5 months ago

πŸ‘Ÿ Reproduction steps

I am using next js 14 with node-appwrite for using authentication by following the steps for appwrite next js auth docs and I am getting this error

"app.**************@service.cloud.appwrite.io (role: applications) missing scope (public)"

And yes I select all the scops for my api key like auth, database and all of them

by following the docs steps for next js ssr authentication with project api key, here is my backend code for auth in next js 14

import { createAuthentication, createMainAdmin } from "@/Appwrite";
import { cookies } from "next/headers";
import { NextResponse } from "next/server";
import { ID } from "node-appwrite";

export async function POST(req) {
    const { name, email, password } = await req.json();
    try {
        const { account } = await createAuthentication();
        const { AdminUsers } = await createMainAdmin();
        const CreateUser = await account.create(
            ID.unique(),
            email,
            password,
            name
        );
        if (CreateUser) {
            const session = await account.createEmailPasswordSession(
                email,
                password
            );
            if (session) {
                cookies().set("session", JSON.stringify(CreateUser), {
                    path: "/",
                    httpOnly: true,
                    sameSite: "strict",
                    secure: true,
                });
                return NextResponse.json(CreateUser, { status: 200 });
            }
        }
    } catch (error) {
        return NextResponse.json({ error: error?.message }, { status: 200 });
    }

}

this code shows me an error

πŸ‘ Expected behavior

It shows me that (role: applications) missing scope (public) error but my all scopes are selected

πŸ‘Ž Actual Behavior

Screenshot 2024-03-28 220924

here is an image for All Scopes are selected

But its not working and showing me an error

🎲 Appwrite version

Version 1.5.x

πŸ’» Operating system

Windows

🧱 Your Environment

I am using appwrite latest node-appwrite version with next js 14 on windows x64

πŸ‘€ Have you spent some time to check if this issue has been raised before?

🏒 Have you read the Code of Conduct?

stnguyen90 commented 5 months ago

@zain-rajpoot, thanks for creating this issue! πŸ™πŸΌ The error you're seeing:

app.**@service.cloud.appwrite.io (role: applications) missing scope (public)

Means you're using an API key (app.**************@service.cloud.appwrite.io (role: applications)) against an API that should be done without any authentication (scope (public)). Please try without an API key.

zain-rajpoot commented 5 months ago

off course I try without an api key it can added user to my Auth BUT not getting the user data ( user info ) whenever I tried to get user data it shows that user is a guest mode or scope.

I'm using nextjs 14 and my api keys are not PUBLIC according to my .env file. I didn't add NEXTPUBLIC with my api key.

And I'm following the Appwrite DOCS for nextjs SSR authentication.

stnguyen90 commented 5 months ago

@zain-rajpoot,

And I'm following the Appwrite DOCS for nextjs SSR authentication.

It doesn't seem like your code is following what's suggested in the docs. For example, you're storing the user into the session:

                cookies().set("session", JSON.stringify(CreateUser), {
                    path: "/",
                    httpOnly: true,
                    sameSite: "strict",
                    secure: true,
                });

which can't be used for authentication. The docs say to use the admin client to create an account and session and then storing the session.secret.

  const { account } = await createAdminClient();

  await account.create(ID.unique(), email, password, name);
  const session = await account.createEmailPasswordSession(email, password);

  cookies().set("my-custom-session", session.secret, {
    path: "/",
    httpOnly: true,
    sameSite: "strict",
    secure: true,
  });

Lastly, would you please verify what API call you're making that's returning the "scope (public)" error? It shouldn't be account.create() or account. createEmailPasswordSession() 🧐

zain-rajpoot commented 5 months ago

hi @stnguyen90

cookies().set("session", JSON.stringify(CreateUser), {
               path: "/",
               httpOnly: true,
               sameSite: "strict",
               secure: true,
               });

In my this cookies section I am storing the complete user data in my cookies just to test it that is it working or not and I just change the files, folders, functions name and routes structure according to me.

And with an api key it is showing me this error

**app.*****@service.cloud.appwrite.io (role: applications) missing scope (public)**

but without an api key it is not getting session.secret to store secret in cookies thats why I add complete user info in cookies just to test it

If there is no session secret it cannot be able to get user info according to this code from docs,

"use server";
import { Client, Account } from "node-appwrite";
import { cookies } from "next/headers";

export async function createSessionClient() {
    const client = new Client()
        .setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT)
        .setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT);

    const session = cookies().get("my-custom-session");
    if (!session || !session.value) {
        throw new Error("No session");
    }

    client.setSession(session.value);

    return {
        get account() {
            return new Account(client);
        },
    };
}

export async function createAdminClient() {
    const client = new Client()
        .setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT)
        .setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT)
        .setKey(process.env.NEXT_APPWRITE_KEY);

    return {
        get account() {
            return new Account(client);
        },
    };
}

export async function getLoggedInUser() {
    try {
        const { account } = await createSessionClient();
        return await account.get();
    } catch (error) {
        return null;
    }
}

Now I follows the docs each steps with same files, folders and routing structure for next js ssr Auth

But I'm still facing the same error

zain-rajpoot commented 5 months ago

Hello @stnguyen90 ,

Are you there,

Reply about that and If you have any solution please suggest me to how to solve this problem

Thanks 😊

stnguyen90 commented 5 months ago

app.*****@service.cloud.appwrite.io (role: applications) missing scope (public)

Wait are you using Appwrite Cloud or your own 1.5 instance of Appwrite?

zain-rajpoot commented 5 months ago

I am using appwrite version 14.0.0 and node-appwrite here is my package.json file

{
  "name": "test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "appwrite": "^14.0.0",
    "next": "14.1.4",
    "node-appwrite": "^12.0.1",
    "react": "^18",
    "react-dom": "^18"
  },
  "devDependencies": {
    "autoprefixer": "^10.0.1",
    "postcss": "^8",
    "tailwindcss": "^3.3.0"
  }
}
stnguyen90 commented 5 months ago

Are you using Appwrite cloud? What are you using for the appwrite endpoint?

zain-rajpoot commented 5 months ago

sorry for not understanding but here is my full code in next js

I just started learning 2 weeks ago and I am familiar with client side

appwrite.js

// src/lib/server/appwrite.js
"use server";
import { Client, Account } from "node-appwrite";
import { cookies } from "next/headers";

export async function createSessionClient() {
    const client = new Client()
        .setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT)
        .setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT);

    const session = cookies().get("my-custom-session");
    if (!session || !session.value) {
        throw new Error("No session");
    }

    client.setSession(session.value);

    return {
        get account() {
            return new Account(client);
        },
    };
}

export async function createAdminClient() {
    const client = new Client()
        .setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT)
        .setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT)
        .setKey(process.env.NEXT_APPWRITE_KEY)

    return {
        get account() {
            return new Account(client);
        },
    };
}

export async function getLoggedInUser() {
    try {
        const { account } = await createSessionClient();
        return await account.get();
    } catch (error) {
        return null;
    }
}

and signup/page.jsx

import { getLoggedInUser } from "@/lib/server/appwrite";

import { ID } from "node-appwrite";
import { createAdminClient } from "@/lib/server/appwrite";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";

async function signUpWithEmail(formData) {
    "use server";
    const email = formData.get("email");
    const password = formData.get("password");
    const name = formData.get("name");
    const { account } = await createAdminClient();
    await account.create(
        ID.unique(),
        email,
        password,
        name
    );
    const session = await account.createEmailPasswordSession(email, password);
    console.log(session);
    console.log(session?.secret);
    cookies().set("my-custom-session", session.secret, {
        path: "/",
        httpOnly: true,
        sameSite: "strict",
        secure: true,
    });

    redirect("/account");
}

export default async function SignUpPage() {
    const user = await getLoggedInUser();
    if (user) redirect("/account");

    return (
        <>
            <form action={signUpWithEmail} className="mx-auto max-w-xl flex justify-center items-center gap-5 flex-col h-screen">
                <input
                    id="email"
                    name="email"
                    placeholder="Email"
                    type="email"
                    className="p-3 rounded-md w-full border-2 border-green-500"
                />
                <input
                    id="password"
                    name="password"
                    placeholder="Password"
                    minLength={8}
                    type="password"
                    className="p-3 rounded-md w-full border-2 border-green-500"
                />
                <input
                    id="name"
                    name="name"
                    placeholder="Name"
                    type="text"
                    className="p-3 rounded-md w-full border-2 border-green-500"
                />
                <button type="submit"
                    className="w-full rounded-md bg-green-400 p-3"
                >Sign up</button>
            </form>
        </>
    );
}
stnguyen90 commented 5 months ago

What is NEXT_PUBLIC_APPWRITE_ENDPOINT in your .env file?

zain-rajpoot commented 5 months ago

https://cloud.appwrite.io/v1

This is my endpoint

zain-rajpoot commented 5 months ago

NEXT_APPWRITE_KEY=

NEXT_PUBLIC_APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1 NEXT_PUBLIC_APPWRITE_PROJECT=6**9e1

zain-rajpoot commented 5 months ago

Screenshot 2024-03-31 235131

I am getting this scopes while creating an api key but I watched video on youtube of appwrite where I am not getting session.write in my scopes

Here is the video

Screenshot 2024-03-31 235535

stnguyen90 commented 5 months ago

https://cloud.appwrite.io/v1

This is my endpoint

You're using Appwrite Cloud which is on version 1.4 (you can see the version at the bottom right of the Appwrite Console), not 1.5. You won't be able to use these 1.5 features on Appwrite Cloud until it's upgraded.

zain-rajpoot commented 5 months ago

Ok So how can I upgrade to 1.5 should I need to be pro plan??

zain-rajpoot commented 5 months ago

Thanks for that helpπŸ™