Prisma-cms boilerplate


#1

Sorry for my english :raised_hands:

In my practice i use prisma for real projects, for example: https://pivkarta.ru/
And I am very grateful to the creators of the Prisma, which helps to create them!:tada:

During this time, I was faced with a mass of decisions that I would like to improve at least for myself. Especially it concerned work with the API scheme. As a result, a part of my developments were united in a series of components under the general name @prisma-cms (I hope this will not be regarded as plagiarism🙌).

Here boilerplate with detailed instruction for install with Prisma Cloud or Prisma local: https://github.com/prisma-cms/boilerplate

Demo (not filled yet): http://prisma-cms.com/users/. Here you can try signup (may not set email) and view users list. And here playground: http://prisma-cms.com/api/ (please, check endpoint setted to http://prisma-cms.com/api/ or got error “Server cannot be reached”).

Case 1. Extend database and API schema
Add module and extend schema.
I create separate branch: https://github.com/prisma-cms/boilerplate/tree/example-1
Add module UserProfile and include them in CoreModule
After i run in command-line endpoint=http://localhost:4466/prisma/dev yarn deploy and got extended database and API.

Schema can be extended by include files or simply as a text:

getSchema(types = []) {

  let schema = fileLoader(__dirname + '/schema/database/', {
    recursive: true,
  });


  if (schema) {
    types = types.concat(schema);
  }
  
  const extendedType = `
    type UserProfile {
      displayName: String
    }
  `;
  
  types = types.concat([extendedType]);


  let typesArray = super.getSchema(types);

  return typesArray;
}

As result we got complete type UserProfile

type UserProfile {
  id: ID! @unique
  User: User! @relation(name: "UserProfile")
  displayName: String
}

and extended type User

type User {
  Profile: UserProfile @relation(name: "UserProfile")
  extended: String
  id: ID! @unique
  createdAt: DateTime!
  updatedAt: DateTime!
  username: String @unique
  ...
  LogedIns: [LogedIn!]! @relation(name: "UserLogedIn")
}

Case 2. Remove some fields from API schema
When Prisma generate API schema, they includes all relations for created types. For example, we can exec this query:

mutation createUserProfile{
  createUserProfile(
    data:{
      displayName:"somename"
      User:{
        create:{
          password: ""
          sudo: true
        }
      }
    }
  ){
    id
    displayName
    User{
      id
      sudo
    }
  }
}

In case if on server side we exec ctx.db.mutation.createUserProfile(args, info) without data filtering, attacker will be able create User object with sudo attribute and empty password.
:warning:This is not necessarily a vulnerability in the Prisma, it is just a general principle of operation and features of my scheme and this sample.
For this reason i want remove User from UserProfile mutation schema.
I can do this by set excludable types and write my custom inputs.
Then i run yarn build-schema-api in command-line and got custom API schema.

This is a small part of the engine. If you’re interested, I’ll write more articles.