Elthel Mario

Elthel Mario

1601369500

Next.js Firebase authentication - Including SSR

Lately, I’ve been playing around with Next.js. In my opinion, this is a great library to get a React-based application up and running.

I was just struggling with the authentication of my application. I like to use the Firebase authentication service, so I wanted to implement this in a Next.js app.

I like to think that one of the nice features of Next JS is the server-side rendering. This allows me to perform all the required calls to my backend or database and to render a static webpage based on data retrieved by these calls. This helps with obvious things like SEO, but also for sharing webpages to social media for example. When you share a webpage on Facebook, it will crawl your page and retrieve some preview data to embed inside of the social network. When some of your data is rendered based on client-side calls, there is a big chance that Facebook will have trouble crawling your application.

Next to that, I like the fact that my end-users aren’t able to look around in my API calls. Firebase is a great platform that provides authentication for your applications. It is really easy to check the user authentications state on the client-side via Firebase. At some point, I wanted to check the authentication state while Server Side Rendering a page. I have been struggling a little to make this work.

In this article, I will show step by step how I ended up with my solution. As always, If you see any issues in my solution or if you have some interesting additions to it, feel free to comment below!

#javascript #nextjs #authentication #firebase

What is GEEK

Buddha Community

Next.js Firebase authentication - Including SSR

NBB: Ad-hoc CLJS Scripting on Node.js

Nbb

Not babashka. Node.js babashka!?

Ad-hoc CLJS scripting on Node.js.

Status

Experimental. Please report issues here.

Goals and features

Nbb's main goal is to make it easy to get started with ad hoc CLJS scripting on Node.js.

Additional goals and features are:

  • Fast startup without relying on a custom version of Node.js.
  • Small artifact (current size is around 1.2MB).
  • First class macros.
  • Support building small TUI apps using Reagent.
  • Complement babashka with libraries from the Node.js ecosystem.

Requirements

Nbb requires Node.js v12 or newer.

How does this tool work?

CLJS code is evaluated through SCI, the same interpreter that powers babashka. Because SCI works with advanced compilation, the bundle size, especially when combined with other dependencies, is smaller than what you get with self-hosted CLJS. That makes startup faster. The trade-off is that execution is less performant and that only a subset of CLJS is available (e.g. no deftype, yet).

Usage

Install nbb from NPM:

$ npm install nbb -g

Omit -g for a local install.

Try out an expression:

$ nbb -e '(+ 1 2 3)'
6

And then install some other NPM libraries to use in the script. E.g.:

$ npm install csv-parse shelljs zx

Create a script which uses the NPM libraries:

(ns script
  (:require ["csv-parse/lib/sync$default" :as csv-parse]
            ["fs" :as fs]
            ["path" :as path]
            ["shelljs$default" :as sh]
            ["term-size$default" :as term-size]
            ["zx$default" :as zx]
            ["zx$fs" :as zxfs]
            [nbb.core :refer [*file*]]))

(prn (path/resolve "."))

(prn (term-size))

(println (count (str (fs/readFileSync *file*))))

(prn (sh/ls "."))

(prn (csv-parse "foo,bar"))

(prn (zxfs/existsSync *file*))

(zx/$ #js ["ls"])

Call the script:

$ nbb script.cljs
"/private/tmp/test-script"
#js {:columns 216, :rows 47}
510
#js ["node_modules" "package-lock.json" "package.json" "script.cljs"]
#js [#js ["foo" "bar"]]
true
$ ls
node_modules
package-lock.json
package.json
script.cljs

Macros

Nbb has first class support for macros: you can define them right inside your .cljs file, like you are used to from JVM Clojure. Consider the plet macro to make working with promises more palatable:

(defmacro plet
  [bindings & body]
  (let [binding-pairs (reverse (partition 2 bindings))
        body (cons 'do body)]
    (reduce (fn [body [sym expr]]
              (let [expr (list '.resolve 'js/Promise expr)]
                (list '.then expr (list 'clojure.core/fn (vector sym)
                                        body))))
            body
            binding-pairs)))

Using this macro we can look async code more like sync code. Consider this puppeteer example:

(-> (.launch puppeteer)
      (.then (fn [browser]
               (-> (.newPage browser)
                   (.then (fn [page]
                            (-> (.goto page "https://clojure.org")
                                (.then #(.screenshot page #js{:path "screenshot.png"}))
                                (.catch #(js/console.log %))
                                (.then #(.close browser)))))))))

Using plet this becomes:

(plet [browser (.launch puppeteer)
       page (.newPage browser)
       _ (.goto page "https://clojure.org")
       _ (-> (.screenshot page #js{:path "screenshot.png"})
             (.catch #(js/console.log %)))]
      (.close browser))

See the puppeteer example for the full code.

Since v0.0.36, nbb includes promesa which is a library to deal with promises. The above plet macro is similar to promesa.core/let.

Startup time

$ time nbb -e '(+ 1 2 3)'
6
nbb -e '(+ 1 2 3)'   0.17s  user 0.02s system 109% cpu 0.168 total

The baseline startup time for a script is about 170ms seconds on my laptop. When invoked via npx this adds another 300ms or so, so for faster startup, either use a globally installed nbb or use $(npm bin)/nbb script.cljs to bypass npx.

Dependencies

NPM dependencies

Nbb does not depend on any NPM dependencies. All NPM libraries loaded by a script are resolved relative to that script. When using the Reagent module, React is resolved in the same way as any other NPM library.

Classpath

To load .cljs files from local paths or dependencies, you can use the --classpath argument. The current dir is added to the classpath automatically. So if there is a file foo/bar.cljs relative to your current dir, then you can load it via (:require [foo.bar :as fb]). Note that nbb uses the same naming conventions for namespaces and directories as other Clojure tools: foo-bar in the namespace name becomes foo_bar in the directory name.

To load dependencies from the Clojure ecosystem, you can use the Clojure CLI or babashka to download them and produce a classpath:

$ classpath="$(clojure -A:nbb -Spath -Sdeps '{:aliases {:nbb {:replace-deps {com.github.seancorfield/honeysql {:git/tag "v2.0.0-rc5" :git/sha "01c3a55"}}}}}')"

and then feed it to the --classpath argument:

$ nbb --classpath "$classpath" -e "(require '[honey.sql :as sql]) (sql/format {:select :foo :from :bar :where [:= :baz 2]})"
["SELECT foo FROM bar WHERE baz = ?" 2]

Currently nbb only reads from directories, not jar files, so you are encouraged to use git libs. Support for .jar files will be added later.

Current file

The name of the file that is currently being executed is available via nbb.core/*file* or on the metadata of vars:

(ns foo
  (:require [nbb.core :refer [*file*]]))

(prn *file*) ;; "/private/tmp/foo.cljs"

(defn f [])
(prn (:file (meta #'f))) ;; "/private/tmp/foo.cljs"

Reagent

Nbb includes reagent.core which will be lazily loaded when required. You can use this together with ink to create a TUI application:

$ npm install ink

ink-demo.cljs:

(ns ink-demo
  (:require ["ink" :refer [render Text]]
            [reagent.core :as r]))

(defonce state (r/atom 0))

(doseq [n (range 1 11)]
  (js/setTimeout #(swap! state inc) (* n 500)))

(defn hello []
  [:> Text {:color "green"} "Hello, world! " @state])

(render (r/as-element [hello]))

Promesa

Working with callbacks and promises can become tedious. Since nbb v0.0.36 the promesa.core namespace is included with the let and do! macros. An example:

(ns prom
  (:require [promesa.core :as p]))

(defn sleep [ms]
  (js/Promise.
   (fn [resolve _]
     (js/setTimeout resolve ms))))

(defn do-stuff
  []
  (p/do!
   (println "Doing stuff which takes a while")
   (sleep 1000)
   1))

(p/let [a (do-stuff)
        b (inc a)
        c (do-stuff)
        d (+ b c)]
  (prn d))
$ nbb prom.cljs
Doing stuff which takes a while
Doing stuff which takes a while
3

Also see API docs.

Js-interop

Since nbb v0.0.75 applied-science/js-interop is available:

(ns example
  (:require [applied-science.js-interop :as j]))

(def o (j/lit {:a 1 :b 2 :c {:d 1}}))

(prn (j/select-keys o [:a :b])) ;; #js {:a 1, :b 2}
(prn (j/get-in o [:c :d])) ;; 1

Most of this library is supported in nbb, except the following:

  • destructuring using :syms
  • property access using .-x notation. In nbb, you must use keywords.

See the example of what is currently supported.

Examples

See the examples directory for small examples.

Also check out these projects built with nbb:

API

See API documentation.

Migrating to shadow-cljs

See this gist on how to convert an nbb script or project to shadow-cljs.

Build

Prequisites:

  • babashka >= 0.4.0
  • Clojure CLI >= 1.10.3.933
  • Node.js 16.5.0 (lower version may work, but this is the one I used to build)

To build:

  • Clone and cd into this repo
  • bb release

Run bb tasks for more project-related tasks.

Download Details:
Author: borkdude
Download Link: Download The Source Code
Official Website: https://github.com/borkdude/nbb 
License: EPL-1.0

#node #javascript

Joel  Hawkins

Joel Hawkins

1632538163

Elk: A Low Footprint JavaScript Engine for Embedded Systems

Elk: a tiny JS engine for embedded systems

Elk is a tiny embeddable JavaScript engine that implements a small but usable subset of ES6. It is designed for microcontroller development. Instead of writing firmware code in C/C++, Elk allows to develop in JavaScript. Another use case is providing customers with a secure, protected scripting environment for product customisation.

Elk features include:

  • Cross platform. Works anywhere from 8-bit microcontrollers to 64-bit servers
  • Zero dependencies. Builds cleanly by ISO C or ISO C++ compilers
  • Easy to embed: just copy elk.c and elk.h to your source tree
  • Very small and simple embedding API
  • Can call native C/C++ functions from JavaScript and vice versa
  • Does not use malloc. Operates with a given memory buffer only
  • Small footprint: about 20KB on flash/disk, about 100 bytes RAM for core VM
  • No bytecode. Interprets JS code directly

Below is a demonstration on a classic Arduino Nano board which has 2K RAM and 30K flash (see full sketch):

Elk on Arduino Nano

JavaScript on ESP32

The Esp32JS Arduino sketch is an example of Elk integration with ESP32. Flash this sketch on your ESP32 board, go to http://elk-js.com, and get a JavaScript development environment instantly! Reloading your script takes a fraction of a second - compare that with a regular reflashing.. Here how it looks like:

The example JS firmware implements:

  • Blinks an LED periodically
  • Connects to the HiveMQ MQTT server
  • Subscribes to the elk/rx topic
  • When an MQTT message is received, sends some stats to the elk/tx topic:

That's screenshot is taken from the MQTT server which shows that we sent a hello JS! message and received stats in response:

Call JavaScript from C

#include <stdio.h>
#include "elk.h"

int main(void) {
  char mem[200];
  struct js *js = js_create(mem, sizeof(mem));  // Create JS instance
  jsval_t v = js_eval(js, "1 + 2 * 3", ~0);     // Execute JS code
  printf("result: %s\n", js_str(js, v));        // result: 7
  return 0;
}

Call C from JavaScript

This demonstrates how JS code can import and call existing C functions:

#include <stdio.h>
#include "elk.h"

// C function that adds two numbers. Will be called from JS
int sum(int a, int b) {
  return a + b;
}

int main(void) {
  char mem[200];
  struct js *js = js_create(mem, sizeof(mem));  // Create JS instance
  jsval_t v = js_import(js, sum, "iii");        // Import C function "sum"
  js_set(js, js_glob(js), "f", v);              // Under the name "f"
  jsval_t result = js_eval(js, "f(3, 4);", ~0); // Call "f"
  printf("result: %s\n", js_str(js, result));   // result: 7
  return 0;
}

Supported features

  • Operations: all standard JS operations except:
    • !=, ==. Use strict comparison !==, ===
    • No ternary operator a ? b : c
    • No computed member access a[b]
  • Typeof: typeof('a') === 'string'
  • While: while (...) { ... }
  • Conditional: if (...) ... else ...
  • Simple types: let a, b, c = 12.3, d = 'a', e = null, f = true, g = false;
  • Functions: let f = function(x, y) { return x + y; };
  • Objects: let obj = {f: function(x) { return x * 2}}; obj.f(3);
  • Every statement must end with a semicolon ;
  • Strings are binary data chunks, not Unicode strings: 'Київ'.length === 8

Not supported features

  • No var, no const. Use let (strict mode only)
  • No do, switch, for. Use while
  • No => functions. Use let f = function(...) {...};
  • No arrays, closures, prototypes, this, new, delete
  • No standard library: no Date, Regexp, Function, String, Number

Performance

Since Elk parses and interprets JS code on the fly, it is not meant to be used in a performance-critical scenarios. For example, below are the numbers for a simple loop code on a different architectures.

let a = 0;        // 97 milliseconds on a 16Mhz 8-bit Atmega328P (Arduino Uno and alike)
while (a < 100)   // 16 milliseconds on a 48Mhz SAMD21
  a++;            //  5 milliseconds on a 133Mhz Raspberry RP2040
                  //  2 milliseconds on a 240Mhz ESP32

Build options

Available preprocessor definitions:

NameDefaultDescription
JS_EXPR_MAX20Maximum tokens in expression. Expression evaluation function declares an on-stack array jsval_t stk[JS_EXPR_MAX];. Increase to allow very long expressions. Reduce to save C stack space.
JS_DUMPundefinedDefine to enable js_dump(struct js *) function which prints JS memory internals to stdout

Note: on ESP32 or ESP8266, compiled functions go into the .text ELF section and subsequently into the IRAM MCU memory. It is possible to save IRAM space by copying Elk code into the irom section before linking. First, compile the object file, then rename .text section, e.g. for ESP32:

$ xtensa-esp32-elf-gcc $CFLAGS elk.c -c elk.tmp
$ xtensa-esp32-elf-objcopy --rename-section .text=.irom0.text elk.tmp elk.o

API reference

js_create()

struct js *js_create(void *buf, size_t len);

Initialize JS engine in a given memory block. Elk will only use that memory block to hold its runtime, and never use any extra memory. Return: a non-NULL opaque pointer on success, or NULL when len is too small. The minimum len is about 100 bytes.

The given memory buffer is laid out in the following way:

  | <-------------------------------- len ------------------------------> |
  | struct js, ~100 bytes  |   runtime vars    |    free memory           | 

js_eval()

jsval_t js_eval(struct js *, const char *buf, size_t len);

Evaluate JS code in buf, len and return result of the evaluation. During the evaluation, Elk stores variables in the "runtime" memory section. When js_eval() returns, Elk does not keep any reference to the evaluated code: all strings, functions, etc, are copied to the runtime.

Important note: the returned result is valid only before the next call to js_eval(). The reason is that js_eval() triggers a garbage collection. A garbage collection is mark-and-sweep, run before every top-level statement gets executed.

The runtime footprint is as follows:

  • An empty object is 8 bytes
  • Each object property is 16 bytes
  • A string is 4 bytes + string length, aligned to 4 byte boundary
  • A C stack usage is ~200 bytes per nested expression evaluation

js_str()

const char *js_str(struct js *, jsval_t val);

Stringify JS value val and return a pointer to a 0-terminated result. The string is allocated in the "free" memory section. If there is no enough space there, an empty string is returned. The returned pointer is valid until the next js_eval() call.

js_import()

jsval_t js_import(struct js *js, uintptr_t funcaddr, const char *signature);

Import an existing C function with address funcaddr and signature signature. Return imported function, suitable for subsequent js_set().

  • js: JS instance
  • funcaddr: C function address: (uintptr_t) &my_function
  • signature: specifies C function signature that tells how JS engine should marshal JS arguments to the C function. First letter specifies return value type, following letters - parameters:
    • b: a C bool type
    • d: a C double type
    • i: a C integer type: char, short, int, long
    • s: a C string, a 0-terminated char *
    • j: a jsval_t
    • m: a current struct js *. In JS, pass null
    • p: any C pointer
    • v: valid only for the return value, means void

The imported C function must satisfy the following requirements:

  • A function must have maximum 6 parameters
  • C double parameters could be only 1st or 2nd. For example, function void foo(double x, double y, struct bar *) could be imported, but void foo(struct bar *, double x, double y) could not
  • C++ functions must be declared as extern "C"
  • Functions with float params cannot be imported. Write wrappers with double

Here are some example of the import specifications:

  • int sum(int) -> js_import(js, (uintptr_t) sum, "ii")
  • double sub(double a, double b) -> js_import(js, (uintptr_t) sub, "ddd")
  • int rand(void) -> js_import(js, (uintptr_t) rand, "i")
  • unsigned long strlen(char *s) -> js_import(js, (uintptr_t) strlen, "is")
  • char *js_str(struct js *, js_val_t) -> js_import(js, (uintptr_t) js_str, "smj")

In some cases, C APIs use callback functions. For example, a timer C API could specify a time interval, a C function to call, and a function parameter. It is possible to marshal JS function as a C callback - in other words, it is possible to pass JS functions as C callbacks.

A C callback function should take between 1 and 6 arguments. One of these arguments must be a void * pointer, that is passed to the C callback by the imported function. We call this void * parameter a "userdata" parameter.

The C callback specification is enclosed into the square brackets [...]. In addition to the signature letters above, a new letter u is available that specifies userdata parameter. In JS, pass null for u param. Here is a complete example:

#include <stdio.h>
#include "elk.h"

// C function that invokes a callback and returns the result of invocation
int f(int (*fn)(int a, int b, void *userdata), void *userdata) {
  return fn(1, 2, userdata);
}

int main(void) {
  char mem[500];
  struct js *js = js_create(mem, sizeof(mem));
  js_set(js, js_glob(js), "f", js_import(js, f, "i[iiiu]u"));
  jsval_t v = js_eval(js, "f(function(a,b,c){return a + b;}, 0);", ~0);
  printf("result: %s\n", js_str(js, v));  // result: 3
  return 0;
}

js_set(), js_glob(), js_mkobj()

jsval_t js_glob(struct js *);   // Return global object
jsval_t js_mkobj(struct js *);  // Create a new object
void js_set(struct js *, jsval_t obj, const char *key, jsval_t val);  // Assign property to an object

These are helper functions for assigning properties to objects. The anticipated use case is to give names to imported C functions.

Importing a C function sum into the global namespace:

  jsval_t global_namespace = js_glob(js);
  jsval_t imported_function = js_import(js, (uintptr_t) sum, "iii");
  js_set(js, global_namespace, "f", imported_function);

Use js_mkobj() to create a dedicated object to hold groups of functions and keep a global namespace tidy. For example, all GPIO related functions can go into the gpio object:

  jsval_t gpio = js_mkobj(js);              // Equivalent to:
  js_set(js, js_glob(js), "gpio", gpio);    // let gpio = {};

  js_set(js, gpio, "mode",  js_import(js, (uintptr_t) func1, "iii");  // Create gpio.mode(pin, mode)
  js_set(js, gpio, "read",  js_import(js, (uintptr_t) func2, "ii");   // Create gpio.read(pin)
  js_set(js, gpio, "write", js_import(js, (uintptr_t) func3, "iii");  // Create gpio.write(pin, value)

js_usage()

int js_usage(struct js *);

Return memory usage percentage - a number between 0 and 100.

Download Details:
Author: cesanta
Download Link: Download The Source Code
Official Website: https://github.com/cesanta/elk 
License: GPLv2

#javascript

 

How To Set Up Two-Factor Authentication in cPanel

What is 2FA
Two-Factor Authentication (or 2FA as it often referred to) is an extra layer of security that is used to provide users an additional level of protection when securing access to an account.
Employing a 2FA mechanism is a vast improvement in security over the Singe-Factor Authentication method of simply employing a username and password. Using this method, accounts that have 2FA enabled, require the user to enter a one-time passcode that is generated by an external application. The 2FA passcode (usually a six-digit number) is required to be input into the passcode field before access is granted. The 2FA input is usually required directly after the username and password are entered by the client.

#tutorials #2fa #access #account security #authentication #authentication method #authentication token #cli #command line #cpanel #feature manager #google authenticator #one time password #otp #otp authentication #passcode #password #passwords #qr code #security #security code #security policy #security practices #single factor authentication #time-based one-time password #totp #two factor authentication #whm

Landen  Brown

Landen Brown

1625985180

Client & SSR Authentication with Next.js in Less than 7 Minutes from Scratch

In this video we’ll start from scratch to build out authentication in a brand new Next.js project to implement client, server, and API route authentication using AWS Amplify and Amazon Cognito.a

#next #next.js #ssr

Eva  Murphy

Eva Murphy

1625674200

Google analytics Setup with Next JS, React JS using Router Events - 14

In this video, we are going to implement Google Analytics to our Next JS application. Tracking page views of an application is very important.

Google analytics will allow us to track analytics information.

Frontend: https://github.com/amitavroy/video-reviews
API: https://github.com/amitavdevzone/video-review-api
App link: https://video-reviews.vercel.app

You can find me on:
Twitter: https://twitter.com/amitavroy7​
Discord: https://discord.gg/Em4nuvQk

#next js #js #react js #react #next #google analytics