Git Product home page Git Product logo

Comments (8)

benjie avatar benjie commented on September 20, 2024

It works for me; are you sure that changing pgStrictFunctions to false definitely solves it? It seems to me that it's probably an RLS policy issue. I don't think subscriptions support JWTs right now - you have to add your own websocketMiddlewares to process request headers.

Here's how I checked:

schema:

create table people (
  id serial primary key,
  name text not null
);

create or replace function tg_notify() returns trigger as $$
begin
  perform pg_notify(tg_argv[0], json_build_object('__node__', json_build_array(tg_argv[1], new.id))::text);
  return NEW;
end;
$$ language plpgsql volatile;

create trigger _500_notify after insert on people for each row execute procedure tg_notify('postgraphile:people:insert', 'people');

server.js:

const http = require("http");
const { postgraphile, makePluginHook } = require("postgraphile");
const {
  default: PostGraphileSupporter
} = require("@graphile/plugin-supporter");

const pluginHook = makePluginHook([PostGraphileSupporter]);

http
  .createServer(
    postgraphile("issue1", "public", {
      graphiql: true,
      pluginHook,
      simpleSubscriptions: true,
      graphileBuildOptions: {
        pgStrictFunctions: true
      }
    })
  )
  .listen(3495);

Create through GraphiQL:

screen shot 2018-11-06 at 21 01 35

Record shows up in Playground:

screen shot 2018-11-06 at 20 57 15

from issues.

tranduchieu avatar tranduchieu commented on September 20, 2024

@benjie Can you tell more about handling RLS policy with websocketMiddlewares?

from issues.

benjie avatar benjie commented on September 20, 2024

Sure, read this:

https://www.graphile.org/postgraphile/subscriptions/#enabling-with-an-express-app

If you have more questions I’m going to need to know more about your app and how you have configured it / how you are expecting the user to be authenticated / etc.

from issues.

tranduchieu avatar tranduchieu commented on September 20, 2024

@benjie This is my configuration
In database i used RSL. If JWT cannot be used in Subscription like Query/Mutation, I do not know how to make the relatedNode not null. You talk about websocketMiddlewares but I havent understood how to solve it.

    {
      pluginHook,
      simpleSubscriptions: true,
      graphiql: true,
      graphileBuildOptions: {
        pgStrictFunctions: true,
      },
      pgDefaultRole: 'guest',
      dynamicJson: true,
      jwtSecret: JWT_SECRET,
      jwtPgTypeIdentifier: 'tocu_schema.jwt_token',
      exportGqlSchemaPath:
        process.env.NODE_ENV === 'production' ? './schema.graphql' : undefined,
      classicIds: true,
      setofFunctionsContainNulls: false,
    },
CREATE SEQUENCE tocu_schema.person_id_seq;

CREATE TABLE tocu_schema.person (
  id int NOT NULL DEFAULT NEXTVAL('tocu_schema.person_id_seq') PRIMARY KEY,
  name text not null CHECK (char_length(name) < 80),
  username citext UNIQUE CHECK (username is not null and username ~* '^[a-z](?:[a-z\d]|-(?=[a-z\d])|\.(?=[a-z\d])){2,38}$'),
  password text,
  role tocu_schema.role_enum not null default 'customer',
  vip boolean not null default false,
  mobile_phone text UNIQUE check(mobile_phone ~ '^(030|031|032|033|034|035|036|037|038|039|050|051|052|053|054|055|056|057|058|059|070|071|072|073|074|075|076|077|078|079|080|081|082|083|084|085|086|087|088|089|090|091|092|093|094|095|096|097|098|099)\d{7}$'),
  mobile_phone_verified boolean DEFAULT FALSE,
  fb_id text unique check (fb_id ~ '^[0-9\.]+$'),
  fb_username text unique check(fb_username ~ '^[a-z\d.]{5,}$'),
  unread_notifications_count integer not null default 0,
  last_notification_id integer references tocu_schema.notification(id) on delete restrict,
  note text,
  created_by integer references tocu_schema.person(id),
  updated_by integer references tocu_schema.person(id),
  created_at timestamp not null DEFAULT now(),
  updated_at timestamp not null DEFAULT now(),
  search_words tsvector
);

CREATE INDEX person_idx ON tocu_schema.person USING GIN(search_words, updated_at, mobile_phone);

comment on table tocu_schema.district is E'@omit create';

grant select on table tocu_schema.person to boss, manager, sales, support_online, customer, shipper, cashier, warehouse_manager, warehouse_staff, visitor;
grant insert, update on table tocu_schema.person to boss, manager, sales, support_online;
grant usage on sequence tocu_schema.person_id_seq to boss, manager, sales, support_online;

-- Row security
alter table tocu_schema.person enable row level security;
create policy select_me on tocu_schema.person for select to boss, manager, sales, support_online, customer, shipper, cashier, warehouse_manager, warehouse_staff, visitor
  using (id = current_setting('jwt.claims.person_id')::integer);
create policy select_customer on tocu_schema.person for select to boss, manager, sales, support_online
  using (true);

create policy insert_person on tocu_schema.person for insert to boss, manager, sales, support_online
  with check (created_by = current_setting('jwt.claims.person_id')::integer);

create policy update_me on tocu_schema.person for update to boss, manager, sales, support_online, customer, shipper, cashier, warehouse_manager, warehouse_staff, visitor
  using (id = current_setting('jwt.claims.person_id')::integer);
create policy update_customer on tocu_schema.person for update to boss, manager, sales, support_online
  using (true);
create or replace function tocu_schema.notification_added_notify()
  returns trigger as $$
begin
  perform pg_notify(
    'postgraphile:notification_added:' || new.id,
    json_build_object(
      '__node__', json_build_array('people', new.id)
    )::text
  );
  return new;
end;
$$
LANGUAGE plpgsql strict SECURITY DEFINER;

create trigger notification_added_notify_trigger after update of last_notification_id on tocu_schema.person
  for each row EXECUTE PROCEDURE tocu_schema.notification_added_notify();

from issues.

benjie avatar benjie commented on September 20, 2024

Ah; I see the issue. You have:

    json_build_object(
      '__node__', json_build_array('people', new.id)
    )::text

but your table is called person not people, so the nodeId you reference does not point to anything. I thought JWT should automatically work! The middlewares are only necessary for sessions/other forms of auth.

from issues.

tranduchieu avatar tranduchieu commented on September 20, 2024

@benjie I think table name = person and node name = people is right, it is not a issue.
If I comment remove line pgDefaultRole: 'guest', relatedNode return data object. If pgDefaultRole is guest return null.

{
  pluginHook,
  simpleSubscriptions: true,
  graphiql: true,
  graphileBuildOptions: {
    pgStrictFunctions: true,
  },
  // pgDefaultRole: 'guest',
  dynamicJson: true,
  jwtSecret: JWT_SECRET,
  jwtPgTypeIdentifier: 'tocu_schema.jwt_token',
  exportGqlSchemaPath:
    process.env.NODE_ENV === 'production' ? './schema.graphql' : undefined,
  classicIds: true,
  setofFunctionsContainNulls: false,
},

return

image

And I found Authorization bearer token key in the header is not effective when using Subscription.

from issues.

benjie avatar benjie commented on September 20, 2024

Ah okay; maybe we don’t yet support JWT via subscriptions. I’ll take a look.

Odd that we use the plural of the table name. That must be a legacy thing.

from issues.

benjie avatar benjie commented on September 20, 2024

v0.8.3 of @graphile/supporter supports JWT in both the HTTP headers and in the initial websocket payload 👍

from issues.

Related Issues (8)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.