Skip to content

Commit

Permalink
continue to write pi post + made image names more semantic
Browse files Browse the repository at this point in the history
  • Loading branch information
Mordechai Dror committed Sep 28, 2023
1 parent b4bf060 commit 474d24a
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 8 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions src/content/posts/_what's-in-my-raspberry-pi.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ RSS protocol is sort of standard contract between tools that blog authors use to

### Bitwarden / Vaultwarden

![Bitwarden Logo](../attachments/what's-in-my-raspberry-pi/bitwarden-logo.svg)

There are multiple options to store your passwords nowadays. I suppose that the default option for an average modern user is either to have only one password for everything or to store all of the passwords in a browser. The major problem of having only one password is that not all your internet accounts are equally protected, but most likely you use the same email address everywhere. A common way of hacking user email account like Gmail, which has strong protection, is to hack some small less-protected buggy site, find there an account with the targeted email address and try to use this password in Gmail, so it's simply not safe. The built-in browsers password manager for me means vendor-lock since I swap browsers from time to time. Thankfully there are plenty of solutions for it outside of major IT monopolies.

> **Whining minute**: modern browsers IMHO should become way more modular, they should not do all at once, they should allow to integrate all at once.
At first many years ago I migrated to 1Password and it was really nice experience. It is standalone subscription-based password manager that exceptionally well integrates itself into both MacOS and iOS. It is even frequently promoted by Apple when they want to demonstrate the amount of apps of their ecosystem. The main problem for me with it was it's monetization approach. While subscription is not active the user can't create new passwords or autofill existing ones. He/she still can view already created passwords and copy-paste them manually, without those capabilities 1Password would be easy no-go for me, but still... Let's be clear, how many new accounts do you need to create each month? I don't do a much. Payment for autofill is just artificial boundary, so what should I pay for on a monthly basis? For the storing the data on their cloud infrastructure? I doubt it cost what they ask for.

So once I bought Raspberry Pi I found a good alternative for 1Password, it is called Bitwarden. From the functionality that I personally use they are pretty equal, there is no such a thing that I used in 1Password, but is in lack in Bitwarden. From the design perspective 1Password is indeed prettier, but Bitwarden is free when you self-host it. So instead of paying for storing my passwords in the cloud, I'm running my own instance and connecting iOS app and MacOS browser extensions to it. As with all other my Pi apps there is a trade-off of being unable to connect to server outside the home. But thankfully all of the Bitwarden clients I used are offline-first: once they synced their data with server, user can disconnect from it, all the synced data is still accessible within the client app.

Only one additional thing to mention is that deployment of Bitwarden server itself can be a little bit hard thing to do from what I remember, there are several different things you need to configure and so on. But since the server is open-source, there is already a solution to it. One of the good people out there implemented a lightweight alternative called Vaultwarden that is fully compatible with official Bitwarden clients, so this is what I use in practice.

One additional bonus to this solution that is worth mentioning is security. The thing is that regardless of the size of company, regardless of how much money they spend to be as secure as possible, once the thing is in the cloud you cannot be 100% protected from malicious attacks. Even if data protected in such a manner that even leaked dataset actually don't benefit hackers at all, still making attack surface as small as possible is the best security strategy. And what can be more secure than hosting the server inside your local network without any access to the Internet? So I suppose Bitwarden / Vaultwarden setup is not only cheaper that everything I used before, but also more secure by definition.

### Firefly III

### Nextcloud
Expand Down
17 changes: 9 additions & 8 deletions src/content/posts/aws-amplify-functions-on-steroids.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ coverImage: ../attachments/aws-amplify-functions-on-steroids/cover.png

When we add an API to Amplify project it out-of-the-box offers us key-value storage to store all of our data (using DynamoDB) and GraphQL-based CRUD API to access it (using AppSync) with a bunch of directives to customize the schema. The customization means we as a developers are not limited to CRUD only. For example, there are a couple of ways to implement a custom resolvers based on our business logic requirements. One of these ways is to define a Lambda function and link it in schema via `@function` directive. Those lambdas can be written in different languages, but we will focus more on Node.JS since it is nice to have the same language ecosystem both on Front-End and Back-End side. In our case there will be three custom mutation resolvers: one to mark all current todos as completed, second to delete all of the completed todos and third to toggle completion of a todo (instead of setting it to either `true` or `false` manually). The UI should look something like this:

![](../attachments/aws-amplify-functions-on-steroids/1.png)
![example project ui](../attachments/aws-amplify-functions-on-steroids/example-project-ui.png)

After we add Amplify to the project, lets define our data model and add a functions to our project (see the official documentation [here](https://docs.amplify.aws/cli/function/) and [here](https://docs.amplify.aws/cli/graphql/custom-business-logic/#lambda-function-resolver) for the exact steps). In the end our schema should look somewhat like this:

![](../attachments/aws-amplify-functions-on-steroids/2.png)
![example project schema](../attachments/aws-amplify-functions-on-steroids/example-project-schema.png)

A couple of side bonuses:

> First thing no note is that Amplify CLI offers to name the function with project name used as a prefix (e.g. `functionsonsteroids1fa063ec`). You would like to follow this pattern (maybe use some shortened version of your project name like in my case it is `fos`) since without in lambdas from different projects with the same name can cause conflicts. When it comes to different environments of the same project Amplify under-the-hood adds suffix of the environment to avoid conflicts, but for some reason it doesn't automatically add project name as prefix, so we need to to it manually.
Expand All @@ -28,7 +29,7 @@ A couple of side bonuses:
So as of now we have three separate JavaScript lambda functions with all the necessary logic already implemented. Here are file structure and code of one of our three lambdas just for a reference:

![](../attachments/aws-amplify-functions-on-steroids/3.png)
![lambdas file structure and javascript code](../attachments/aws-amplify-functions-on-steroids/lambdas-file-structure-and-javascript-code.png)

Our goals are:

Expand All @@ -37,7 +38,7 @@ Our goals are:
- Get types for them from Amplify CLI Codegen
- Have as less trade-offs as possible

![](../attachments/aws-amplify-functions-on-steroids/4.jpg)
![goals](../attachments/aws-amplify-functions-on-steroids/goals.jpg)

### TypeScript support

Expand All @@ -57,7 +58,7 @@ The last point of time that I mentioned earlier is Amplify CI/CD. Since as of no

After all the preparation is done, we can now re-write the actual JS code of the lambda to be TS. Additionally I added `.gitignore` in `src` of lambda, because we don't need to store transpilation result in the source code. Let's just manually copy-paste required AppSync types from generated UI code for now. We will make it way a lot more DRY in the next step. In the meanwhile here are updated file structure and source code of another one of our lambdas for reference (I put all the copy-pasted AppSync types into `app-sync.models.ts` and moved `appSyncRequest` function to `app-sync.helpers.ts`).

![](../attachments/aws-amplify-functions-on-steroids/5.png)
![lambdas file structure and typescript code](../attachments/aws-amplify-functions-on-steroids/lambdas-file-structure-and-typescript-code.png)

### Sharing code between lambdas

Expand All @@ -67,9 +68,9 @@ Both those options are about sharing JavaScript code, but since we migrated to T

- Since there are two `rootDirs` for TS compiler, the actual structure of the resulting JS inside `src` is changed (see the screenshot) and AWS Lambda runner points to actual entry file no more. We can narrow down this issue to purely cosmetic one by manually editing CloudFormation templates of lambdas (and its `package.json#main` property as well) so it will take into account a new file structure e.g.

![](../attachments/aws-amplify-functions-on-steroids/6.png)
![build output of lambda with multiple root dirs](../attachments/aws-amplify-functions-on-steroids/build-output-of-lambda-with-multiple-root-dirs.png)

![](../attachments/aws-amplify-functions-on-steroids/7.png)
![lambda handler change in cloud formation template](../attachments/aws-amplify-functions-on-steroids/lambda-handler-change-in-cloud-formation-template.png)

- Amplify CLI cannot detect lambda changes if only a shared code is changed. It doesn't matter for CI/CD since we are ignoring all `.js` files, which means it will build it each time, but locally we might need to build lambda manually from time to time so `amplify push` can catch the stuff up.

Expand All @@ -83,7 +84,7 @@ Both those options are about sharing JavaScript code, but since we migrated to T

Now that we have a good support for TS it and we placed removed repetitive code, it would be nice just like in UI to benefit from auto-generated types based on our AppSync schema. According to this GitHub [issue](https://github.com/aws-amplify/amplify-codegen/issues/49) there is no support for multiple targets in Amplify Codegen at the moment, but... Since Amplify stores Codegen config as a file in the root of our repo we can update it manually to our needs and Codegen will do what we want him to do without any problem... Just don't tell this secret to anyone😜

![](../attachments/aws-amplify-functions-on-steroids/8.png)
![multi-target codegen](../attachments/aws-amplify-functions-on-steroids/multi-target-codegen.png)

> For some reason it only works if you agreed to generate all possible operations and types during adding or re-adding Codegen. Otherwise Codegen throws an exception that multiple projects are not supported.
Expand Down

0 comments on commit 474d24a

Please sign in to comment.