awslabs / amplify-video

An open source Category Plugin for the AWS Amplify-CLI that makes it easy to deploy live and file based streaming video services and integrate them into your Amplify applications.
https://www.npmjs.com/package/amplify-category-video
Apache License 2.0
267 stars 56 forks source link

"Validation error of type FieldUndefined: Field 'token' #217

Open tscole opened 3 years ago

tscole commented 3 years ago

Note: If your question is regarding the AWS Amplify Console service, please log it in the official AWS Amplify Console forum

I am trying to use production mode with signed URLs. I can not access the "token". When I try it directly in the AppSync console I get "Validation error of type FieldUndefined: Field 'token'

wizage commented 3 years ago

Do you mind sharing your schema here from the Amplify CLI so we can take a look at what you are currently using?

Thanks, Sam Patzer

tscole commented 3 years ago
type Curriculum @model @auth(rules: [{ allow: owner, operations: [create, delete, update] }]) {
  id: ID!
  title: String!
  introduction: String
  series: [Series] @connection(name: "CurriculumSeries")
}

type Series @model @auth(rules: [{ allow: owner, operations: [create, delete, update] }]) {
  id: ID!
  title: String!
  introduction: String
  curriculum: Curriculum @connection(name: "CurriculumSeries")
  lessons: [Lesson] @connection(name: "SeriesLessons")
}

type Lesson @model @auth(rules: [{ allow: owner, operations: [create, delete, update] }]) @key(name: "ByOwner", fields: ["owner"], queryField: "lessonsByOwner") {
  id: ID!
  title: String!
  author: String
  ages: String
  roomSize: String
  introduction: String
  series: Series @connection(name: "SeriesLessons")
  sections: [Section] @connection(name: "LessonSections")
  owner: String
}

type Section @model @auth(rules: [{ allow: owner, operations: [create, delete, update] }]) {
  id: ID!
  title: String!
  introduction: String
  index: Int
  sectionLessonId: String
  lesson: Lesson @connection(name: "LessonSections")
  elements: [SectionElement] @connection(keyName: "bySection", fields: ["id"])
}

type SectionElement
@model
@auth(rules: [{ allow: owner, operations: [create, delete, update] }])
@key(name: "bySection", fields: ["sectionID", "elementID"])
@key(name: "byElement", fields: ["elementID", "sectionID"]) {
  id: ID!
  sectionID: ID!
  elementID: ID!
  index: Int
  section: Section! @connection(fields: ["sectionID"])
  element: Element! @connection(fields: ["elementID"])
}

type Element @model @auth(rules: [{ allow: owner, operations: [create, delete, update] }]) {
  id: ID!
  title: String
  type: String
  introduction: String
  outline: String
  script: String
  notes: String
  materials: String
  ageRange: String
  duration: String
  roomSize: String
  seasons: String
  themes: String
  stories: String
  characters: String
  references: String
  assets: [Asset] @connection(name: "ElementAssets")
  vodAsset: vodAsset @connection
  sections: [SectionElement] @connection(keyName: "byElement", fields: ["id"])
}

type Asset @model @auth(rules: [{ allow: owner, operations: [create, delete, update] }]) {
  id: ID!
  name: String!
  contentType: String!
  userFederatedID: String!
  file: S3Object
  element: Element @connection(name: "ElementAssets")
}

type S3Object @aws_iam @aws_cognito_user_pools {
  region: String!
  bucket: String!
  key: String!
}

type vodAsset @model (subscriptions: {level: public})
@auth(
  rules: [
    {allow: owner, ownerField: "owner", operations: [create, update, delete, read] },
    {allow: private, operations: [read]}
  ]
)
{
  id:ID!
  title:String!
  description:String!

  #DO NOT EDIT
  video:videoObject @connection
}

#DO NOT EDIT
type videoObject @model
@auth(
  rules: [
    {allow: owner, ownerField: "owner", operations: [create, update, delete, read] },
    {allow: private, operations: [read]}
  ]
)
{
  id:ID!
}
wizage commented 3 years ago

Ahhh this is a bug!

For right now, you can manually add it:

#DO NOT EDIT
type videoObject @model
@auth(
  rules: [
    {allow: owner, ownerField: "owner", operations: [create, update, delete, read] },
    {allow: private, operations: [read]}
  ]
)
{
  id:ID!
  token: String @function(name: "")
}

And inside the quotes place the lambda name, it should look something like this: <projectname>-<env>-tokenGen but verify in the lambda console. A fix will go out soon!

tscole commented 3 years ago

Thanks. I'm using this in a three developer team and we have multiple environments including dev, production and sandboxes :) Adding the function manually will potentially be problematic as I guess each env will need its own. We're about six weeks away from launching the product. Happy to help with testing, etc if that will assist you in speeding up a fix. Let me know!

wizage commented 3 years ago

Fix is easy enough to push forward and do! I will take a stab and put in on a beta branch for you asap :)

tscole commented 3 years ago

That's great - thank you

wizage commented 3 years ago

Beta is published here: npm i amplify-category-video@3.3.1-Beta1 -g

Steps to move to this new version:

  1. Remove videoObject and videoAsset from your schema file.
  2. Run amplify video update and answer the questions like so:
    1. When prompted if you want to run production say Yes
    2. Answer 'Yes' again if you see a prompt to add signed URLs.
    3. If you don't see a yes/no question, but are prompted with rotating your credentials, please rotate your credentials for the changes to take effect!
    4. Select Yes on adding a GraphQL API and it will spot your existing API
    5. Choose your permission model
    6. Finally make sure that answer to append the schema we create to your existing one!

Hopefully this works!

Niretech commented 3 years ago

Hi @wizage - I work with @tscole.

I've tried the steps above. Installed the beta package and ran an amplify scan, eemoved both videoObject and vodAsset, ran amplify video update and gone through the exact steps above.

The message at the end is Schema already configure. To edit it please open: C:\VueJS\wbs-platform\amplify\backend\api\wbsplatform\schema.graphql. The schema however doesn't change and nothing for video is added in. Is there a step missing or does the bug still remain?

Thanks

tscole commented 3 years ago

@wizage I've just followed the steps through as well - I wasn't asked about appending to existing schema and no videoObject / videoAsset models are made.

wizage commented 3 years ago

Hmmmmm sounds like you didn't save the graphql or edited the wrong file.

Make sure you are modifying this exact file: C:\VueJS\wbs-platform\amplify\backend\api\wbsplatform\schema.graphql

Remove the entire type for both videoObject and videoAsset and make sure to save it. I have verified it does work as intended. The message saying your already configured means that it found both videoObject and videoAsset in your schema already.

tscole commented 3 years ago

@wizage Just tried this again as follows:

? Choose what project you want to update? videostreams ? Select a system-provided encoding template, specify an already-created template name: Default HLS Adaptive Bitrate ? Is this a production enviroment? Yes ? Do you want to protect your content with signed urls? Yes ? Do you want Amplify to create a new GraphQL API to manage your videos? (Beta) Yes Using wbsplatform to manage API ? Define your permission schema (Press to select, to toggle all, to invert selection)Admins can only upload videos Schema already configure. To edit it please open: /Users/timcole/Development/wbs/wbs-platform/amplify/backend/api/wbsplatform/schema.graphql ✔ All resources built. Successfully updated videostreams

The graphql was not updated:

type Curriculum
    @model
    @auth(rules: [{ allow: owner, operations: [create, delete, update] }]) {
    id: ID!
    title: String!
    introduction: String
    series: [Series] @connection(name: "CurriculumSeries")
}

type Series
    @model
    @auth(rules: [{ allow: owner, operations: [create, delete, update] }]) {
    id: ID!
    title: String!
    introduction: String
    curriculum: Curriculum @connection(name: "CurriculumSeries")
    lessons: [Lesson] @connection(name: "SeriesLessons")
}

type Lesson
    @model
    @auth(rules: [{ allow: owner, operations: [create, delete, update] }])
    @key(name: "ByOwner", fields: ["owner"], queryField: "lessonsByOwner") {
    id: ID!
    title: String!
    author: String
    ages: String
    roomSize: String
    introduction: String
    series: Series @connection(name: "SeriesLessons")
    sections: [Section] @connection(name: "LessonSections")
    owner: String
}

type Section
    @model
    @auth(rules: [{ allow: owner, operations: [create, delete, update] }]) {
    id: ID!
    title: String!
    introduction: String
    index: Int
    sectionLessonId: String
    lesson: Lesson @connection(name: "LessonSections")
    elements: [SectionElement] @connection(keyName: "bySection", fields: ["id"])
}

type SectionElement
    @model
    @auth(rules: [{ allow: owner, operations: [create, delete, update] }])
    @key(name: "bySection", fields: ["sectionID", "elementID"])
    @key(name: "byElement", fields: ["elementID", "sectionID"]) {
    id: ID!
    sectionID: ID!
    elementID: ID!
    index: Int
    section: Section! @connection(fields: ["sectionID"])
    element: Element! @connection(fields: ["elementID"])
}

type Element
    @model
    @auth(rules: [{ allow: owner, operations: [create, delete, update] }]) {
    id: ID!
    title: String
    type: String
    introduction: String
    outline: String
    script: String
    notes: String
    materials: String
    ageRange: String
    duration: String
    roomSize: String
    seasons: String
    themes: String
    stories: String
    characters: String
    references: String
    vodFileName: String
    assets: [Asset] @connection(name: "ElementAssets")
    vodAsset: vodAsset @connection
    sections: [SectionElement] @connection(keyName: "byElement", fields: ["id"])
}

type Asset
    @model
    @auth(rules: [{ allow: owner, operations: [create, delete, update] }]) {
    id: ID!
    name: String!
    contentType: String!
    userFederatedID: String!
    file: S3Object
    element: Element @connection(name: "ElementAssets")
}

type S3Object @aws_iam @aws_cognito_user_pools {
    region: String!
    bucket: String!
    key: String!
}
wizage commented 3 years ago

Hey @tscole

In your Element you still reference vodAsset: vodAsset @connection

We do a search for any vodAsset or vodObject as to not collide with your schema.

You can either add it manually by copying this to the end of your schema or remove this line temporarily and then answering the questions.

type vodAsset @model (subscriptions: {level: public})
@auth(
  rules: [
    {allow: groups, groups:["Admin"], operations: [create, update, delete, read]},
    {allow: private, operations: [read]}
  ]
)
{
  id:ID!
  title:String!
  description:String!

  #DO NOT EDIT
  video:videoObject @connection
} 

#DO NOT EDIT
type videoObject @model
@auth(
  rules: [
    {allow: groups, groups:["Admin"], operations: [create, update, delete, read]},
    {allow: private, operations: [read]}
  ]
)
{
  id:ID!
  token: String @function(name: "myvodstreams-${env}-tokenGen")
}
armenr commented 3 years ago

^^ This just helped me figure out a problem I've been fighting for days. :)