Posts by sophie

Whatever it Takes

I’m not sure what I’m chasing,

But it’s certainly something beautiful.

It’s there, just the shape is blurry.

It’s a beautiful feeling.

That makes up my whole world.

Brighten my sky.

Secure Gmail Access with OAuth2 and 2LO in Express Backend


Use Express backend to send email from a gmail account.


Use nodemailer to send email with OAuth2 for obtaining access token, during which “two-legged OAuth” (2LO) is used for signature, which directly obtain the access token without manual user consent.


  • A gmail account belonging to a G Suite Domain. We’ll configure the gmail account for 2LO and use it to send emails in the Express backend
  • A google project used to keep the service account we’ll create. The google project doesn’t necessarily the node project we’re talking about. The main purpose of creating a google project is to use it create a service account


  • “googleapis” for handling authentication and authorization using JWT [1]
  • “nodemailer” for sending email using the gmail account [2]


  • Create service account [7]
    • Select the google project demonstrated in the “Prerequisites” section during creating service account
    • Select “Service Account Token Creator” as the role for the service account as we’re using the service account to generate auth tokens
  • Authorize domain-wide authorization to the service account. The G Suite Account used in domain-wide authorization contains the gmail used to send email from Express backend [8]
  • Preparing to make an authorized API call with Google API Client Libraries:
    • Instruction: prepare to make an authorized API call [2]
    • Google API NodeJS Client Repo [1]
  • Send email from the gmail account with the created service account and access token obtained in the previous step
    • explanation of 2LO in nodemailer [3]
    • instruction of using access token [4]
    • example of using access token [5]
    • here’s a full example of NodeJS code of sending email with OAuth2 and 2LO:



[1] Google API NodeJS Client.

[2] Preparing to Make an Authorized API Call.

[3] Explanation of Two-Legged OAuth (2LO) in nodemailer.

[4] Using access token for HTTP request. “HTTP/REST” section of

[5] Example of using access token in nodemailer.

[6] Nodemailer.

[7] Create Service Account in Google.

[8] Authorize domain-wide authorization to the service account. The G Suite Account used in domain-wide authorization contains the gmail used to send email from Express backend.

Note of An Image Synthesizer

Ken Perlin. An Image Synthesizer.

The paper proposes the initial algorithm of Perlin Noise, and a few variations of the algorithm to simulate a variety of randomnesses in nature.

The technique produces organic randomness appears in nature. It proposes an algorithm to produce random look, which is made uniformly distributed by a narrow bandpass limit in frequency. This statistic character of the randomness maintains unchanged with varying domains. Because the algorithm satisfies statistical invariances under rotation and translation.

The most beautiful part of the paper is the description of Perlin Noise: an organized array, when associated with the gradient of the organized array and an augmentation value, both are stochastic, is transformed to a stochastic value which is used together with the gradient to interpolate areas between the stochastic value of the current organized array and the ones of other organized arrays. NOTE: the augmentation arguments for all organized arrays determines the generated stochastic values. The distribution of the augmentation arguments of all organized arrays determines the uniformness of the generated stochastic values.

Note of Simulating and Analyzing Jackson Pollock’s Painting

Sangwon Lee, Sven C. Olsen, Bruce Gooch. Simulating and Analysing Jackson Pollock’s Painting

The paper devises a system to allow user create Pollock-like painting with a painting material simulator which allows user paint without using real material, and with real-time feedback of fractal properties of the ongoing painting, which gives user an awareness of the similarity between the fractal dimension of the ongoing painting and those of Pollock’s painting. That means, the user is capable of creating Pollock-like painting by keeping the similarity high.

The paper points out that fractal dimension is incapable of distinguishing fractal and nonfactual images, and proposes an new metric, uniformity, to alleviate the limitation. Uniformity indicates the similarity between the fractal dimension of a subregion and those of the entire painting. But, in what way does uniformity distinguish fractal and nonfactual images better than fractal dimension does?

Notes of Empathic Painting: Interactive Stylization Through Observed Emotional State

Maria Shugrina, Margrit Betke, John Collomoss. Empathic Painting: Interactive stylization through observed emotional state

Emotion is majorly expressed from a combination of color and stroke. The paper analyzes color, stroke denotation style, and region turbulence to transform them to emotions. It can be found in Section 4.2 Rendering Parameters:

Express Emotion in Region Turbulence

  • Section 4.2.1 Region Turbulence

Express Emotion in Color

  • Section 4.2.2 Tonal Variation, and

Express Emotion in Stroke Denotation Style

  • Section 4.2.3 Stroke Denotation Style

Notes of The Art of Journey

Characters are segmented to make it possible to animate.

Scary faces comes from a question that “what if the character you control is on the dark side?”

Principles of expressing emotions using landscape composition:

  • Openness, happiness: if the fog is pushed away from the player, the view becomes clear, which makes player feel happier; on the other hand, if the fog is close to the player, the blurry view makes the player feel scary
  • Blue sky is used to award the player at the end of the game. Green skies were used earlier as a random alternative of the blue sky, from what the artist said
  • Dreamy and high quality light is used to make the player feel magical at the end of the game

Book link:

Case Study: Debug HTTP ERROR 500 of Azure Web App Which Works Locally

The purpose of this blog is to record the turning points of fixing a crashed web app on Azure, which works locally.


The web app is built with ExpressJS as the backend, sequelize as the ORM, Azure PostgreSQL as the database, React and Redux as frontend. It’s hosted on Azure.


The web app runs on local browser, but crashes on Azure after it’s deployed. The broken website on Azure shows “HTTP ERROR 500”.

Turning Points

  • Azure log stream

Log stream printed out a detailed error when the deployed web app is browsed from azure portal: “TypeError: Cannot read property ‘use_env_variable’ of undefined”. This error happens on the first line of the following code block on model/index.js:

if (config.use_env_variable) {
var sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
var sequelize = new Sequelize(config.database, config.username, config.password, config);

  • Debug var values with console.log

The real issue was unveiled by seeing different value of the same var `env` when assessing var values related to “config” in the import-header section:

var env = process.env.NODE_ENV || ‘development’;
var configFile = require(__dirname + ‘/../config/config.json’);
var config = configFile[env];
var db = {};

console.log(“[DEBUGGING] __dirname”, __dirname);
console.log(“[DEBUGGING] configFile: “, configFile);
console.log(“[DEBUGGING] env: “, env);
console.log(“[DEBUGGING] config: “, config);

Specifically, `var` is `development` on local machine, but is `production` on Azure. Whereas the config.json file specifying database configuration doesn’t have the `production` key.


Looking back, I realize the key to fix the “HTTP ERROR 500” error of the Azure web app is precisely identifying the problem. That means, I needed to figure out on which line of code and which vars didn’t work as expected. This statement holds firmly because that’s the nature of an application wrote by a programming language.

Then, what’s the most effective way of precisely identifying the problem? Turns out using debugging tool to log as much related values of the application as possible is the right way, at least for this case.

However, I didn’t take the most effective approach at the first sight! Specifically, for “HTTP ERROR 500”, I searched online, and got hints of logging application states. That directed me to check Azure’s log stream. But for “TypeError: Cannot read property ‘use_env_variable’ of undefined”, I had wrong guess of the cause of the issue: I imagined the compilers on Azure and on my local machine are different – the compiler on local machine ignores the TypeError detected on Azure. Even worse, I firmly believed my imagination of the cause of the issue is true.. It was me randomly logged the var values that helped me unveiling the real issue.

The native approach I took to fix the problem unveils some mistakes I made for solving tech problems:

  • I should’ve directly check Azure’s diagnostic tools when saw “HTTP ERROR 500”. But understanding and learning “HTTP ERROR 500” was necessary.
  • I should’ve realized “TypeError: Cannot read property ‘use_env_variable’ of undefined” means “config” is undefined, and should’ve logged out related vars of “config”, instead of imagining the difference between local machine and Azure compiler. I think what I really miss here is that for a web app, the first priority of debugging is logging out vars, then consider system and compilers issues. But learning “TypeError: Cannot read property ‘use_env_variable’ of undefined” was necessary too.

So, a couple lessons here to solve an issue

  • Learn the error by googling
  • Use the right debugging tool to precisely identify the issue – it should be specific to code level

Aesthetics Possibilities of Real-Time Sky Rendering

With GLSL implementation of atmospheric scattering, it’s easy to change aesthetics of sky and see the effect on the fly.

Normal Sky:


Dreamy Sky with Aesthetic Changes:

  • Sky color: red and yellow
  • Painting layers: two layers with one red sky and one yellow sky mixed together. Math operation: add
  • Painting effect: turbulent view directions
  • Sky pattern: big blocks

Lastly, a sunrise animation created in a few seconds benefited from the real-time performance of GLSL:

纯净 明亮 清晰 clean, bright, and clear

沉浸于 稀稀疏疏 飘升的乐符 sinking, in the scattered, rising musical notes

开始附着于 飘渺的声线 being attached to, the flying voice

渐渐的 飘起 slowly, floating up

自由的 滑翔 gliding..

尘埃消失 dust.. is falling away.. fading..

世界变得清晰 明亮 the world becomes clear, bright

透彻又纯净 thorough and clean

心底的能量 the warmth underneath the heart

冉冉出现 starts to spread..

发出热量 emitting energies

舞蹈 with the rhythm

滑翔 rising up and rising down

朝着明亮温暖的方向 along the bright and warm way