Web Push API - alternatives for saving VAPID Private key in Database - mongodb

I am currently working on the implementation of push notifications. To do this, the web push api requires the subscription object which contains the public as well as the private key. Additionally the subscription needs to be stored in a database for later use.
#################
#Subscription Object
#################
endpoint: { type: String, unique: true},
keys: {
p256dh: {type: String},
auth: {type: String}
},
#################
#Sending the Notification
#################
webpush.sendNotification(subscription, payload).catch(console.log);
Personally, I am not sure if I should save the private key in the database.
Is there a better approach to this?
Or is it actually safe to store this information in this format?

Related

Using another table field as owner field for DataStore Authentication

Which Category is your question related to?
DataStore (GraphQL API)
Amplify CLI Version
7.6.23
What AWS Services are you utilizing?
DataStore (GraphQL API)
Provide additional details e.g. code snippets. Be sure to remove any sensitive data.
I am trying to build a service where people can buy subscriptions to certain "Persons" and consume their information. I want to restrict people so that they can only access the data of a certain medium when they are subscribed to it.
Here is the basic structure:
type Post #model {
id: ID!
text: String!
personID: ID! #index(name: "byPerson")
person: Person! #belongsTo(fields: ["personID"])
}
type Person #model {
id: ID!
name: String!
posts: [Post] #hasMany(indexName: "byPerson", fields: ["id"])
}
type Subscription #model {
id: ID!
personID: ID! #index(name: "byPerson")
person: Person! #belongsTo(fields: ["personID"])
userSub: String! // or whatever data we need to reference the user
}
So we have Subscriptions to Persons and Persons can have multiple posts. It is not necessary to fetch a Person if you want to fetch the Posts that a user should be able to see.
What should be possible:
Users should only be able to fetch the posts of the persons that they are subscribed to. There are two ways that I can think of doing but they all require me to change/update data. Since all the data is present, I am not a fan of such solutions.
Solution #1:
Add a group to each user, attach it to the post and add the user to the group as soon as he subscribed
type Post #model #auth(rules: [{ allow: groups, groupsField: "groups" }]) {
id: ID!
text: String!
personID: ID! #index(name: "byPerson")
person: Person! #belongsTo(fields: ["personID"])
groups: String!
}
Not a fan, it requires me to create a group each time a Person is created and I basically have duplicated information here with each post.
Solution #2:
Use an owner field and attach the user as soon as he subscribes
type Post #model #auth(rules: [{ allow: owner, ownerField: "subscribers" }]) {
id: ID!
text: String!
personID: ID! #index(name: "byPerson")
person: Person! #belongsTo(fields: ["personID"])
subscribers: [String]
}
Not a fan as well, I need to edit all the postings as soon as a user subscribes/cancels his subscriptions. The margin of error and amount of calculations here could be huge
I have thought about using a custom resolver (no idea if that works, I don't fully understand it yet) or a custom lambda auth check. The custom lambda auth check causes some issues in the frontend with DataStore. Apparently I need to manually refresh the token for the API or something like that.
What do I want to do?
I would love to use the subscription userSub field as an owner field for the posts. Is that possible (with DataSync) in any way?

MongoDB, insert many only if no match

I'm making a token system along with a payment rule.
I need an idempotent rule that will generate some token for user (One for each token he bought)
So i have the following token
{
_id?: ObjectId;
owner: ObjectId;
type: string;
origin: {
paymentIntentId: string;
date: Date;
}
}
It can exists multiple tokens for one paymentIntentId but if multiple call try to create token for the same token (let's say 4) for one paymentIntentId that already own token, i would like to prevent or do a no-op.
How can i proceed ?
I'm having concurrency issue with prevent me to first query then update because the A check appears before the B insert.
Best regards

Reuse OpenAPI/Swagger definition with different validation rules?

Let’s say I have a REST API with a User resource. There are three methods that work with the User resource: POST to create, GET to download and PATCH to change. All methods operate on the same User type, but have different required properties – when creating the user using POST, all request fields except the user ID are mandatory, when downloading using GET, all response fields are mandatory including the ID, when changing using PATCH, all request fields are optional and nullable.
Can I succintly describe this in OpenAPI/Swagger? I would like to describe the User type just once and then only say which fields are required/nullable for each method. A bit like this, in pseudocode:
definitions:
User:
properties:
id:
type: integer
name:
type: string
…
paths:
/users
post:
request:
schema: User
required: [name, …]
nullable: […]
response:
schema: User
required: [id, name, …]
nullable: […]
/users/{id}:
get:
response:
schema: User
required: [id, name, …]
nullable: […]
patch:
request:
schema: User
required: []
nullable: [name, …]
This way I would not have to repeat all the field definitions while having the particular constraints described for each method. Is that possible? Does it make sense?

In a RESTful system, how to make request to a unique server api that doesn't have an id

Now my system has some api that doesn't have an unique id, so how to make request from ember data.
Because find method needs an id, but i don't have it.
Current, my solution is use pure AJAX call to fetch this kind of data.
So is there have any better solution to make this happen.
I guess you should be using DS.RESTSerializer, if so you could specific custom primaryKey for each Model or global to your app.
For Global App.
App.ApplicationSerializer = DS.RESTSerializer({
primaryKey: 'customId'
});
If your behavior is for a couple model, you do the same for those models.
App.MyModel = DS.Model.extend({
name: DS.attrs('string')
});
App.MyModelSeriliazer = App.ApplicationSerializer.extend({
primaryKey: 'customId'
});
EmberJS would map this customId to id in ember-data.

Understanding Mongoose Schema better

I am relatively new to the MongoDb world, coming from a MS Sql / Entity framework environment.
I am excited about Mongo, because of:
MongoDb's ability to dynamically change the shape of the class/table/collection at run time.
Entity framework does not offer me that.
Why is that so important?
Because I would like to create a generic inventory app and have the product class/collection/table be dynamic for clients to add fields pertinent to their business that cannot be used by everyone, eg. Vin Number, ISBN number, etc.
Now I have come to learn about Mongoose and how it offers a schema, which to me detracts from the flexibility of MongoDb described above.
I have read in a few sections that there is such an animal as mixed-schema, but that appears to be dynamic relative to the data type and not the collection of properties for the given class/collection/table.
So this is my question:
If I am looking at developing a generic class/collection /table that affords clients to shape it to include whatever fields/properties they want that pertain to their business, dynamically, should I abandon the whole notion of mongoose?
I found a benefit today as to where a Schema may be warranted:
Allow me to preface though and say I still thoroughly am excited about the whole idea that Mongo allows a collection to be reshaped at run time in circumstances where I may need ti to be. As mentioned above, a perfect example would be an Inventory app where I would want each client to add respective fields that pertain to their business as opposed to other clients, such as a Car dealership needing a VIN Number field, or a Book store needing a ISBN Number field.
Mongo will allow me to create one generic table and let the client shape it according to his own wishes for his own database at run time - SWEET!
But I discovered today where a schema would be appropo:
If in another table that will not be 're-shapeable', say a user table, I can create a Schema for pre-determined fields and make them required, as such:
var dbUserSchema = mongoose.Schema({
title: {type:String, required:'{PATH} is required!'},
FullName: {
FirstName: {type: String, required: '{PATH} is required!'},
LastName: {type: String, required: '{PATH} is required!'}
}
});
By having the respective first-name and last-name required from the schema, the database will not add any records for a user if they are not both included in the insert.
So, I guess one gets the best of both worlds: Tables that can be re-shaped and thru a schema, tables that can be rigid.