Giter Site home page Giter Site logo

rpitv / glimpse-api Goto Github PK

View Code? Open in Web Editor NEW
3.0 5.0 0.0 3.63 MB

Backend API for the RPI TV Glimpse website

Home Page: https://rpi.tv

License: MIT License

Shell 0.01% Dockerfile 0.17% TypeScript 99.71% JavaScript 0.11%
rpi rpitv rensselaer rcos graphql hacktoberfest docker

glimpse-api's Issues

Meta: Documentation

Documentation is lackluster for this repository. I have been working on improving it within the repository's wiki. A set of goals needs to be outlined for what we want documented in order for this issue to be considered "complete"

  • Introduction/NestJS
  • Authentication flow (Passport.js)
  • Authorization flow (@rule)
  • Query complexities
  • CASL integration
  • Prisma integration/migrations
  • Prisma types
  • StreamModule
  • Glossary
  • GraphQL Input types
  • Database bootstrapping
  • Deployment/Docker

https://github.com/rpitv/glimpse-api/wiki

This is carried over from #53

Add Prisma generator to generate CRUD resolvers

The current CrudGenerator is janky and hard to maintain. It also has unsafe type casting due to the limitations of Prisma. Adding a Prisma generator should hopefully resolve these issues.

Login via RPI/Discord

Login via username/password is the only way to login at the moment. Login via Discord and RPI account would speed things up for the user and take the burden of password management off of Glimpse.

To be clear, Glimpse must still support passwords; not everyone will have Discord or RPI account, and passwords are required for LDAP. However, for users who do not use LDAP and have a Discord or RPI account, passwords wouldn't need to be stored for these accounts if they don't set them up.

Feature: Running in HTTPS

While this application is designed to run behind a proxy, there is still a slight security benefit to still keeping things encrypted behind the proxy. It would be nice if we could add support to run this application with HTTPS enabled. This will require coordination with https://github.com/rpitv/glimpse-ui.

Note that, while more secure, running the app with HTTPS enabled will require slightly more processing time. It isn't necessarily something that we should just do because we can, but it would be good to have the option.

Add Docker support

Vagrant is currently supported, however a Docker file should also be written for production.

Feature: Discord integration

Ideally, almost everything the user can do on the website, they'd be able to do in Discord, and vice versa. Consequently, any updates to the website should also update Discord and vice versa.

This will likely require heavily marrying this repository with https://github.com/rpitv/glimpse-discord: perhaps to the point where it doesn't even make sense to have them as two separate repositories anymore.

I think a good starting point may be to set up the API to communciate with glimpse-discord via RabbitMQ to notify it when to create a new Discord channel. From there, we can evaluate whether it makes sense to continue over RabbitMQ or to merge codebases entirely.

NestJS Framework

The current foundation of the API is confusing and poorly documented. Due to the security and stability implications involved, it's important to make sure developers have a good understanding of the code that they are working on. Transitioning to a highly supported and well documented framework seems like the best first step to doing this, and NestJS is the current obvious choice.

Work on this issue is already being done in the nestjs branch.

Feature todo list (bolded are required for merge):

  • GraphQL API
    • findManyX parameters
      • Pagination
        • Cursor-based pagination
        • Offset-based pagination
      • Sorting
        • Sorting authorization
      • Filtering
        • Filtering authorization
    • Subscriptions
    • Query complexity restrictions
  • Authenticaction
    • Local via username and password
    • Discord via OAuth
    • RPI via SAML
    • Session storage
  • Authorization
    • findOneX resolvers
    • findManyX resolvers
    • createX resolvers
    • updateX resolvers
    • deleteX resolvers
    • count resolvers
  • Prisma ORM
    • Generic Prisma resolver generator (DRY)
  • Image uploading
  • Test suite
    • Resolver tests
    • Authorization tests
    • Authentication tests
  • In-depth documentation

Anything not completed by merge should likely have it's own issue created for it.

Authentication Support

The database currently does not support any methods of authentication or authorization. This must be changed before deployment.

Improve Video datatype in schema

The current Video datatype isn't strict at all: it allows for its videoType property to be any integer, and it's data property to contain any data, some which may or may not be related to the videoType, and may not contain required data. This should be improved, but I'm not sure what the best way to go about it is yet.

Bug: Input variables can only be used in the top level of queries

The current StartStream GraphQL snippet in https://github.com/rpitv/glimpse-ui is as follows:

mutation StartStream($to: String!, $from: String!) {
  createStream(input: {to: $to, from: $from}) {
    from
    to
  }
}

Currently, the API will complain about this, as variables are only allowed to be used at the top level of query inputs, e.g.:

mutation StartStream($input: CreateStreamInput!) {
  createStream(input: $input) {
    from
    to
  }
}

The fix in #61 may have broken this further, and as a result, a release should not be made until this issue is resolved and/or further testing is done.

Meta: Build Workflow running slow

I've noticed that the build action takes quite a long time: ~40 minutes, as opposed to ~1-2 minutes on my local computer. We should try to improve this through caching, if possible. If we aren't able to get build times below 10 minutes, some sort of backup plan could be integrated for critical hotfixes.

createPerson without providing a start date fails

When you attempt to create a new Person using GraphQL, it responds with the following error:

{
  "errors": [
    {
      "message": "Unexpected error.",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "createPerson"
      ],
      "extensions": {
        "originalError": {
          "message": "\nInvalid `)).create()` invocation in\n/usr/src/app/src/CrudGenerator.ts:286:12\n\n  283 // Create the object. Permissions have already been checked by @Auth directives.\n  284 return await (<any>(\n  285     ctx.prisma[modelNameToPrismaDelegateMap[modelName]]\n→ 286 )).create({\n        data: {\n          name: 'Billy Wu',\n      +   start: DateTime,\n      ?   pronouns?: String | null,\n      ?   graduation?: DateTime | null,\n      ?   end?: DateTime | null,\n      ?   description?: String | null,\n      ?   blogPosts?: {\n      ?     create?: BlogPostCreateWithoutAuthorInput | BlogPostCreateWithoutAuthorInput | BlogPostUncheckedCreateWithoutAuthorInput | BlogPostUncheckedCreateWithoutAuthorInput,\n      ?     connectOrCreate?: BlogPostCreateOrConnectWithoutAuthorInput | BlogPostCreateOrConnectWithoutAuthorInput,\n      ?     createMany?: BlogPostCreateManyAuthorInputEnvelope,\n      ?     connect?: BlogPostWhereUniqueInput | BlogPostWhereUniqueInput\n      ?   },\n      ?   credits?: {\n      ?     create?: CreditCreateWithoutPersonInput | CreditCreateWithoutPersonInput | CreditUncheckedCreateWithoutPersonInput | CreditUncheckedCreateWithoutPersonInput,\n      ?     connectOrCreate?: CreditCreateOrConnectWithoutPersonInput | CreditCreateOrConnectWithoutPersonInput,\n      ?     createMany?: CreditCreateManyPersonInputEnvelope,\n      ?     connect?: CreditWhereUniqueInput | CreditWhereUniqueInput\n      ?   },\n      ?   images?: {\n      ?     create?: PersonImageCreateWithoutPersonInput | PersonImageCreateWithoutPersonInput | PersonImageUncheckedCreateWithoutPersonInput | PersonImageUncheckedCreateWithoutPersonInput,\n      ?     connectOrCreate?: PersonImageCreateOrConnectWithoutPersonInput | PersonImageCreateOrConnectWithoutPersonInput,\n      ?     createMany?: PersonImageCreateManyPersonInputEnvelope,\n      ?     connect?: PersonImageWhereUniqueInput | PersonImageWhereUniqueInput\n      ?   },\n      ?   roles?: {\n      ?     create?: RoleCreateWithoutPersonInput | RoleCreateWithoutPersonInput | RoleUncheckedCreateWithoutPersonInput | RoleUncheckedCreateWithoutPersonInput,\n      ?     connectOrCreate?: RoleCreateOrConnectWithoutPersonInput | RoleCreateOrConnectWithoutPersonInput,\n      ?     createMany?: RoleCreateManyPersonInputEnvelope,\n      ?     connect?: RoleWhereUniqueInput | RoleWhereUniqueInput\n      ?   },\n      ?   users?: {\n      ?     create?: UserCreateWithoutPersonInput | UserCreateWithoutPersonInput | UserUncheckedCreateWithoutPersonInput | UserUncheckedCreateWithoutPersonInput,\n      ?     connectOrCreate?: UserCreateOrConnectWithoutPersonInput | UserCreateOrConnectWithoutPersonInput,\n      ?     createMany?: UserCreateManyPersonInputEnvelope,\n      ?     connect?: UserWhereUniqueInput | UserWhereUniqueInput\n      ?   }\n        }\n      })\n\nArgument start for data.start is missing.\n\nNote: Lines with + are required, lines with ? are optional.\n",
          "stack": "Error: \nInvalid `)).create()` invocation in\n/usr/src/app/src/CrudGenerator.ts:286:12\n\n  283 // Create the object. Permissions have already been checked by @Auth directives.\n  284 return await (<any>(\n  285     ctx.prisma[modelNameToPrismaDelegateMap[modelName]]\n→ 286 )).create({\n        data: {\n          name: 'Billy Wu',\n      +   start: DateTime,\n      ?   pronouns?: String | null,\n      ?   graduation?: DateTime | null,\n      ?   end?: DateTime | null,\n      ?   description?: String | null,\n      ?   blogPosts?: {\n      ?     create?: BlogPostCreateWithoutAuthorInput | BlogPostCreateWithoutAuthorInput | BlogPostUncheckedCreateWithoutAuthorInput | BlogPostUncheckedCreateWithoutAuthorInput,\n      ?     connectOrCreate?: BlogPostCreateOrConnectWithoutAuthorInput | BlogPostCreateOrConnectWithoutAuthorInput,\n      ?     createMany?: BlogPostCreateManyAuthorInputEnvelope,\n      ?     connect?: BlogPostWhereUniqueInput | BlogPostWhereUniqueInput\n      ?   },\n      ?   credits?: {\n      ?     create?: CreditCreateWithoutPersonInput | CreditCreateWithoutPersonInput | CreditUncheckedCreateWithoutPersonInput | CreditUncheckedCreateWithoutPersonInput,\n      ?     connectOrCreate?: CreditCreateOrConnectWithoutPersonInput | CreditCreateOrConnectWithoutPersonInput,\n      ?     createMany?: CreditCreateManyPersonInputEnvelope,\n      ?     connect?: CreditWhereUniqueInput | CreditWhereUniqueInput\n      ?   },\n      ?   images?: {\n      ?     create?: PersonImageCreateWithoutPersonInput | PersonImageCreateWithoutPersonInput | PersonImageUncheckedCreateWithoutPersonInput | PersonImageUncheckedCreateWithoutPersonInput,\n      ?     connectOrCreate?: PersonImageCreateOrConnectWithoutPersonInput | PersonImageCreateOrConnectWithoutPersonInput,\n      ?     createMany?: PersonImageCreateManyPersonInputEnvelope,\n      ?     connect?: PersonImageWhereUniqueInput | PersonImageWhereUniqueInput\n      ?   },\n      ?   roles?: {\n      ?     create?: RoleCreateWithoutPersonInput | RoleCreateWithoutPersonInput | RoleUncheckedCreateWithoutPersonInput | RoleUncheckedCreateWithoutPersonInput,\n      ?     connectOrCreate?: RoleCreateOrConnectWithoutPersonInput | RoleCreateOrConnectWithoutPersonInput,\n      ?     createMany?: RoleCreateManyPersonInputEnvelope,\n      ?     connect?: RoleWhereUniqueInput | RoleWhereUniqueInput\n      ?   },\n      ?   users?: {\n      ?     create?: UserCreateWithoutPersonInput | UserCreateWithoutPersonInput | UserUncheckedCreateWithoutPersonInput | UserUncheckedCreateWithoutPersonInput,\n      ?     connectOrCreate?: UserCreateOrConnectWithoutPersonInput | UserCreateOrConnectWithoutPersonInput,\n      ?     createMany?: UserCreateManyPersonInputEnvelope,\n      ?     connect?: UserWhereUniqueInput | UserWhereUniqueInput\n      ?   }\n        }\n      })\n\nArgument start for data.start is missing.\n\nNote: Lines with + are required, lines with ? are optional.\n\n    at Document.validate (/usr/src/app/node_modules/@prisma/client/runtime/index.js:47823:20)\n    at PrismaClient._executeRequest (/usr/src/app/node_modules/@prisma/client/runtime/index.js:49972:17)\n    at consumer (/usr/src/app/node_modules/@prisma/client/runtime/index.js:49916:23)\n    at /usr/src/app/node_modules/@prisma/client/runtime/index.js:49920:76\n    at runInChildSpan (/usr/src/app/node_modules/@prisma/client/runtime/index.js:49133:12)\n    at /usr/src/app/node_modules/@prisma/client/runtime/index.js:49920:20\n    at AsyncResource.runInAsyncScope (node:async_hooks:203:9)\n    at PrismaClient._request (/usr/src/app/node_modules/@prisma/client/runtime/index.js:49919:86)\n    at /usr/src/app/node_modules/@prisma/client/runtime/index.js:46474:25\n    at _callback (/usr/src/app/node_modules/@prisma/client/runtime/index.js:46233:52)"
        }
      }
    }
  ],
  "data": null
}

Adding a start variable to the input resolves this issue, however the start variable is intended to be optional, defaulting to the current time.

CRUD generator doesn't include a "count" property

When using pagination, a total number of documents is required to set up pagination correctly. It's not practical (let alone possible) to request all documents at once to get the total count. A simple "count" generator should be created in the CRUD generator which returns this value. For example, if 12 groups exist in the database, then querying "groupCount" would return 12.

In terms of what permissions this would require, it should return all the documents which match the filter from getAccessibleByFilter. This is what is checked for each individual record as well. Any documents which the user does not have permission to read any field on should not be included in the count.

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.