たれぱんのびぼーろく

わたしの備忘録、生物学とプログラミングが多いかも

AWS-Amplifyの中身、とくにAuth

amazon-cognito-identity-jsに強く依存.

signIn()内でcreateCognitoUserしてる。createCognitoUserはCognitoUser()のラッパー。

    public signIn(username: string, password: string): Promise<any> {
        ...  
        const user = this.createCognitoUser(username);
        const authDetails = new AuthenticationDetails({
            Username: username,
            Password: password
        });

        const that = this;
        return new Promise((resolve, reject) => {
            user.authenticateUser(authDetails, {

createCognitoUserメソッドの元クラス (AuthClass) がuserPool属性を持っていて、この中にclientオブジェクトがしまってある。 Auth.configureでCognitoUserPool (amazon-cognito-identity-js由来) を使ってusePoolを設定してるので、おそらくここで一意に決まってくる。
Auth.configure(config)のconfigに入っているものがまんま使われており、この中にendpointがある模様。Amplifyチェック!

    private createCognitoUser(username: string): Cognito.CognitoUser {
        const userData: ICognitoUserData = {
            Username: username,
            Pool: this.userPool,
        };
        ...
        return new CognitoUser(userData);
    }

CognitoUserコンストラクタでdataを引数にとり、そこでthis.client (Clientクラス) にdata.Pool.clientを設定。

export default class CognitoUser {
  constructor(data) {
    ...
    this.username = data.Username || '';
    this.pool = data.Pool;
    this.Session = null;

    this.client = data.Pool.client;

Clientのコンストラクタでendpointを受け取って、以降は一切いじらない。nullの場合はcognito-idp...のドメインになる。
client.requestのリクエスト先ドメインはここで決まる。

// Facet.ts
import * as Cognito from 'amazon-cognito-identity-js';
// /src/Common/index.ts
export * from './Facet';
// /src/Auth/Auth.ts
import {
    AWS,
    Cognito,
    ...,
} from '../Common';

リクエスト実体
// @param {CognitoUserPool} data.Pool

this.client = data.Pool.client;

import Client from './Client';
CognitoUserPoolコンストラクタ内
this.client = new Client(region, endpoint);

client.requestはシンプルなfetch()
aws-amplify/Client.js at master · aws/aws-amplify · GitHub

パスワードでのダイレクト認証はメインとも限らない
authenticateUserDefaultAuthが色々やってて面白い
InitiateAuthリクエストをして、
RespondToAuthChallengeリクエストして、

ドキュメントにもそうある。

最新の認証フローはユーザーのアイデンティティを検証するため、パスワードの他に新しいチャレンジタイプを組み込んでいます。当社では 2 つの一般的なステップで認証を定型化し、InitiateAuth と RespondToAuthChallenge という 2 つの API を使用して実装します

Secure Remote Password (SRP) プロトコル
パスワードから生成した何かで認証するプロトコル
パスワードが通信路に流れないのでセキュア

SRP 計算を回避する場合にセキュアなバックエンドサーバーで使用できるように設計された管理 API の代替セットもあります。

SRPうんぬんはまさに認証なので、OIDCがスコープ外にしてる認証部分なんだろう
つまりUserPools-IdPの認証部分。
でもこれ、クライアントの仕事…?
あ、わかった。
組み込みUIってこの部分が担当だろ
つまりホントのホントの認証部分にも当然、認証クライアントが必要なのでそこの話だ
2FAを組み込んだり色々有り得るから、一般化された内容になってると。おー。

UserPool-IdPでUserPools認証する場合、OIDC AuthNリクエストは走るのかな?
resにクライアントがパスワードぶち込んですぐ認証的な

マッハ書籍に関する叡智のまとめ

ブラウザとモジュールとバージョン管理

ブラウザはモジュールを持つか

ブラウザとモジュール

モジュール化は綺麗で管理しやすく安全なコードを生む。
モジュールは最高だ。
そして今や、ブラウザ(フロントエンド)でもモジュールは使える

モジュールは単体で動くのが主たる仕事ではない。
他のモジュールと共同して動くのだ。
そのためには、モジュールの読み込みが必要だ。

ブラウザの長きにわたる問題点は、モジュール読み込みの不在だった。
Scriptタグの連打とグローバル空間の汚染は最悪で、jsファイル内からは読み込みすら不可能だった。
しかしそれは過去のもの、全てはimportが解決した。

import

import ~~~ from “module_name”;

主要ブラウザは全て、import文に対応している.
Can I use... Support tables for HTML5, CSS3, etc

Node.jsではフラグ立てれば使える.
モジュールチーム
GitHub - nodejs/modules: Node.js Foundation Modules Team

モジュール解決

次の段階は、import対象だ。
つまり、import ~~~ from “module_name”; のmodule_nameだ。
対象のディレクトリをハードコードしたくない
つまり、module specifierの管理であり、module resolutionとそのalgorithmだ。

GitHub - domenic/package-name-maps: How to solve the web's "bare import specifier" problem

ESモジュール特有のつらみ、そこから生まれる問題と解決策

ESモジュールはブラウザで使われる。
そしてブラウザはモジュールをインターネット越しにダウンロードする。
ゆえにモジュール読み込みはとても時間がかかる。
モジュールを読み込むたびに実行していると、日が暮れてしまう。
だからESモジュールでは(commonJSとは異なり) モジュール解決とモジュール実行を非同期にしている。
そのつらみの結果、モジュール名に変数を入れられない問題が発生する。
なぜなら変数は、コードを実行しないと生まれないからだ。
変数はロードするモジュールの分岐等に有用なため、つらい。

そこで出てくるのがDynamic import、つまり実行後のモジュールimportだ。

モジュール解決の現状

webpack

resolve.alias to your webpack.config.js
How to avoid relative path hell in JavaScript / TypeScript projects – @goenning

I think babel has something like this using ‘@/thing/…’, but I don’t use babel.

It’s called modules resolving and webpack can do it too: https://webpack.js.org/configuration/resolve/. Take a look :)

参考文献

スーパークール必読参考文献

hacks.mozilla.org

Shadow DOMとcomposition

Web Componentsの一要素であるShadow DOM.
Shadow DOMを有効に利用するためには、compositionの概念がとても重要。
このcompositionについて解説してみた。

Shadow DOMとは

web標準に颯爽と現れた期待の新人 (新人ではない)
切り離されたDOM、のようなもの.
切り離されているので、CSSの影響を受けないし、アクセスもできない.
切り離されているので、独自のCSSをもつしそれは外部へ出ていかない.

compositionとは

組み立て、構成、合成のような意味の英語.
複数の個別要素をがっちゃんこして新しい機能get!なノリ

DOMにおけるcomposition

HTML/DOMでは、我々は日常的に、無意識のうちにcomposition, 組み立てをしている。
別々の機能を持つ要素を組み立ててパワーアップする、次が好例
\<ul> + \<li> -> 番号無しリスト
\<ol> + \<li> -> 番号付きリスト
組み立ての表記法は単純で、親子関係.
HTMLはcompositionをしまくることで個別機能をサービスに組み立てている(composition)とみることができる.

Shadow DOMにおけるcomposition

切り離されたDOMは、名前空間の問題などを解決してくれる。
しかし、完全に切り離されていると不便極まりない。
そこで出てくるのがcomposition, 組み立て.
compositionの概念により、別々のDOMを組み立ててより優れた機能を得るのだ!

Shadow DOMをもつ要素を\<original-card>とする。\<original-card>はカード型の見た目を提供してくれるとする.
\<original-card>のなかにボタンを付ける、つまり\<original-card>\<button>をcompositionすれば、さらによい働きをしてくれるはず!
しかし、ShadowDOMは本体のDOM (LightDOM) と隔離されているので、単純に次のように書いてもcompositionできない…

<original-card>
  <button>push!</button>
<original-card>

そこで登場するのがslot要素。slot要素はShadow DOM内で利用する要素.
Shadow DOMを作る際に

<power-card>
  <p>私に力を分けてくれ!</p>
  <slot></slot>
</power-card>

のようにしておくと、LightDOMとcomposition可能になるのだ!
つまり、

// LightDOM
<power-card>
  <button>OK!</button>
</power-card>

と書くと、Shadow DOMとcompositionされて

<power-card>
  <p>私に力を分けてくれ!</p>
  <button>OK!</button>
<power-card>

のように働いてくれるのである!
これ便利か?と一瞬思うが、実はとても便利。
ShadowDOMはLightDOMと切り離されているので、CSSが奇麗。
そしてpower-cardは単体で機能するので簡単にライブラリ化できる。
この要素に好きな要素を一瞬でcompositionできるんですよ、これはすごい.
もし先の元気ボタンにNOをさらにつけたかったら、

// LightDOM
<power-card>
  <button>OK!</button>
  <button>NO</button>
</power-card>

と書くだけで、compositionされた後には

<power-card>
  <p>私に力を分けてくれ!</p>
  <button>OK!</button>
  <button>NO</button>
<power-card>

のようになっている。

Web Componentsの実践

依存ファイルはwcの中に。重複してもパフォーマンスに影響ないよ

Don't worry if that means including redundant ; as long as you set appropriate cache headers, these will only be fetched and loaded once
webcomponents.org - Discuss & share web components

設定の注入には属性を使う

Attributes for data in. Use attributes to pass configuration in

built-in要素と同様に動くのが大原則.
だから属性値による設定が大切.

Custom elements, like their built-in counterparts, should be configurable.
Custom Element Best Practices  |  Web Fundamentals  |  Google Developers

attribute, propertyの変更が要素の変更へ即座に反映されるよう

Aim to keep primitive data attributes and properties in sync, reflecting from property to attribute, and vice versa.
Custom Element Best Practices  |  Web Fundamentals  |  Google Developers

1つのコンポーネントに詰め込むのか
あるいはコンポーネントの連鎖で作るのか

styling

Componentsにどうやってスタイルをつけるか

link要素が相性よくない。CSSをlink要素で読み込むのがあまり望ましくない.
Style要素が基本.

外部CSSの場合、

@import url("url")

をStyle要素内で使えば良い。

Plus Ultra

効率の良いDOM更新がほかの大きなテーマ.
VDOMやlit-html系やら

template literals + innerHTML でWeb Componentsを作ってみると性能普通な今どきな書き方 (not 命令型 but 宣言型) ができる.

HTML/DOM/CSS

  • コンポーネント
    • WebComponents
  • DOM更新
    • VDOM (React etc)
    • lit-html系 (template element based?)
  • data binding
  • 記法 (命令型・宣言型)

    • 宣言型
      • lit-html
      • JSX
  • Systematic Styling

GitHubのEvent

GitHub REST API v3 の EVENT API

全部で40Events (多い…)

commit
merge
issue
pull request
とりあえずこのあたりがメインかな

4: CreateEvent
17: IssueEvent
30: PullRequestEvent
34: ReleaseEvent
35: RepositoryEvent

そうか、GitHub的にはcommitはなくて、commitがpushされてくるのか.