Skip to content

Commit bf70d86

Browse files
authored
Merge pull request #1 from Code-Hex/add/linter
added linter and prettier
2 parents dc32265 + 883e53e commit bf70d86

26 files changed

+1693
-885
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dist

.eslintrc.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
const { defineConfig } = require('eslint-define-config');
2+
3+
module.exports = defineConfig({
4+
root: true,
5+
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
6+
parser: '@typescript-eslint/parser',
7+
parserOptions: {
8+
sourceType: 'module',
9+
ecmaVersion: 2021,
10+
},
11+
plugins: ['@typescript-eslint', 'import'],
12+
globals: {
13+
fetch: false,
14+
Response: false,
15+
Request: false,
16+
addEventListener: false,
17+
},
18+
rules: {
19+
quotes: ['error', 'single'],
20+
semi: ['error', 'never'],
21+
'no-debugger': ['error'],
22+
'no-empty': ['warn', { allowEmptyCatch: true }],
23+
'no-process-exit': 'off',
24+
'no-useless-escape': 'off',
25+
'prefer-const': [
26+
'warn',
27+
{
28+
destructuring: 'all',
29+
},
30+
],
31+
'@typescript-eslint/ban-types': [
32+
'error',
33+
{
34+
types: {
35+
Function: false,
36+
},
37+
},
38+
],
39+
'sort-imports': 0,
40+
'import/order': [2, { alphabetize: { order: 'asc' } }],
41+
42+
'node/no-missing-import': 'off',
43+
'node/no-missing-require': 'off',
44+
'node/no-deprecated-api': 'off',
45+
'node/no-unpublished-import': 'off',
46+
'node/no-unpublished-require': 'off',
47+
'node/no-unsupported-features/es-syntax': 'off',
48+
49+
'@typescript-eslint/no-empty-function': ['error', { allow: ['arrowFunctions'] }],
50+
'@typescript-eslint/no-empty-interface': 'off',
51+
'@typescript-eslint/no-inferrable-types': 'off',
52+
'@typescript-eslint/no-var-requires': 'off',
53+
'@typescript-eslint/consistent-type-imports': ['error', { prefer: 'type-imports' }],
54+
'@typescript-eslint/no-explicit-any': 'off',
55+
},
56+
});

.prettierrc.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"trailingComma": "es5",
3+
"printWidth": 120,
4+
"singleQuote": true,
5+
"arrowParens": "avoid"
6+
}

example/index.ts

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,54 @@
1-
import { Auth, emulatorHost, EmulatorEnv, WorkersKVStoreSingle } from "../src";
1+
import type { EmulatorEnv } from '../src';
2+
import { Auth, emulatorHost, WorkersKVStoreSingle } from '../src';
23

34
interface Bindings extends EmulatorEnv {
4-
EMAIL_ADDRESS: string
5-
PASSWORD: string
6-
FIREBASE_AUTH_EMULATOR_HOST: string
7-
PUBLIC_JWK_CACHE_KV: KVNamespace
8-
PROJECT_ID: string
9-
PUBLIC_JWK_CACHE_KEY: string
5+
EMAIL_ADDRESS: string;
6+
PASSWORD: string;
7+
FIREBASE_AUTH_EMULATOR_HOST: string;
8+
PUBLIC_JWK_CACHE_KV: KVNamespace;
9+
PROJECT_ID: string;
10+
PUBLIC_JWK_CACHE_KEY: string;
1011
}
1112

12-
const signInPath = "/identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=test1234"
13+
const signInPath = '/identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=test1234';
1314

1415
export async function handleRequest(req: Request, env: Bindings) {
15-
const url = new URL(req.url)
16-
const firebaseEmuHost = emulatorHost(env)
17-
if (url.pathname === "/get-jwt" && !!firebaseEmuHost) {
18-
const firebaseEmulatorSignInUrl = "http://" + firebaseEmuHost + signInPath
16+
const url = new URL(req.url);
17+
const firebaseEmuHost = emulatorHost(env);
18+
if (url.pathname === '/get-jwt' && !!firebaseEmuHost) {
19+
const firebaseEmulatorSignInUrl = 'http://' + firebaseEmuHost + signInPath;
1920
const resp = await fetch(firebaseEmulatorSignInUrl, {
20-
method: "POST",
21+
method: 'POST',
2122
body: JSON.stringify({
2223
email: env.EMAIL_ADDRESS,
2324
password: env.PASSWORD,
2425
returnSecureToken: true,
2526
}),
2627
headers: {
27-
"Content-Type": "application/json"
28-
}
29-
})
30-
return resp
28+
'Content-Type': 'application/json',
29+
},
30+
});
31+
return resp;
3132
}
3233

33-
const authorization = req.headers.get('Authorization')
34+
const authorization = req.headers.get('Authorization');
3435
if (authorization === null) {
3536
return new Response(null, {
3637
status: 400,
37-
})
38+
});
3839
}
39-
const jwt = authorization.replace(/Bearer\s+/i, "")
40+
const jwt = authorization.replace(/Bearer\s+/i, '');
4041
const auth = Auth.getOrInitialize(
4142
env.PROJECT_ID,
4243
WorkersKVStoreSingle.getOrInitialize(env.PUBLIC_JWK_CACHE_KEY, env.PUBLIC_JWK_CACHE_KV)
43-
)
44-
const firebaseToken = await auth.verifyIdToken(jwt, env)
44+
);
45+
const firebaseToken = await auth.verifyIdToken(jwt, env);
4546

4647
return new Response(JSON.stringify(firebaseToken), {
4748
headers: {
48-
"Content-Type": "application/json"
49-
}
50-
})
49+
'Content-Type': 'application/json',
50+
},
51+
});
5152
}
5253

53-
export default { fetch: handleRequest };
54+
export default { fetch: handleRequest };

package.json

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,47 @@
11
{
22
"name": "firebase-auth-cloudflare-workers",
33
"version": "1.0.0",
4-
"description": "firebase auth token verifier for Cloudflare Workers.",
5-
"author": "Kei Kamikawa <[email protected]>",
4+
"description": "Zero-dependencies firebase auth library for Cloudflare Workers.",
5+
"author": "codehex",
66
"license": "MIT",
77
"scripts": {
88
"test": "jest",
99
"start-firebase-emulator": "firebase emulators:start --project example-project12345",
10-
"start-example": "wrangler dev example/index.ts --config=example/wrangler.toml --local=true"
10+
"start-example": "wrangler dev example/index.ts --config=example/wrangler.toml --local=true",
11+
"prettier": "prettier --write --list-different \"**/*.ts\"",
12+
"prettier:check": "prettier --check \"**/*.ts\"",
13+
"lint": "eslint --ext .ts .",
14+
"lint-fix": "eslint --fix --ext .ts ."
1115
},
1216
"dependencies": {},
1317
"devDependencies": {
1418
"@cloudflare/workers-types": "^3.14.0",
1519
"@types/jest": "^28.1.3",
20+
"@typescript-eslint/eslint-plugin": "^5.30.5",
21+
"@typescript-eslint/parser": "^5.30.5",
22+
"eslint": "^8.19.0",
23+
"eslint-config-prettier": "^8.5.0",
24+
"eslint-define-config": "^1.5.1",
25+
"eslint-import-resolver-typescript": "^3.2.4",
26+
"eslint-plugin-eslint-comments": "^3.2.0",
27+
"eslint-plugin-import": "^2.26.0",
1628
"firebase-tools": "^11.2.0",
1729
"jest": "^28.1.2",
1830
"jest-environment-miniflare": "^2.5.1",
31+
"prettier": "^2.7.1",
1932
"ts-jest": "^28.0.5",
2033
"typescript": "^4.7.4",
2134
"wrangler": "^2.0.16"
35+
},
36+
"keywords": [
37+
"web",
38+
"app",
39+
"jwt",
40+
"firebase",
41+
"cloudflare",
42+
"workers"
43+
],
44+
"bugs": {
45+
"url": "https://github.com/Code-Hex/firebase-auth-cloudflare-workers/issues"
2246
}
2347
}

src/auth.ts

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,15 @@
1-
import { EmulatorEnv, useEmulator } from "./emulator";
2-
import { KeyStorer } from "./key-store";
3-
import {
4-
createIdTokenVerifier,
5-
FirebaseIdToken,
6-
FirebaseTokenVerifier,
7-
} from "./token-verifier";
1+
import type { EmulatorEnv } from './emulator';
2+
import { useEmulator } from './emulator';
3+
import type { KeyStorer } from './key-store';
4+
import type { FirebaseIdToken, FirebaseTokenVerifier } from './token-verifier';
5+
import { createIdTokenVerifier } from './token-verifier';
86

97
export class BaseAuth {
108
/** @internal */
119
protected readonly idTokenVerifier: FirebaseTokenVerifier;
1210

13-
constructor(
14-
projectId: string,
15-
keyStore: KeyStorer,
16-
) {
17-
this.idTokenVerifier = createIdTokenVerifier(
18-
projectId,
19-
keyStore
20-
);
11+
constructor(projectId: string, keyStore: KeyStorer) {
12+
this.idTokenVerifier = createIdTokenVerifier(projectId, keyStore);
2113
}
2214

2315
/**

src/base64.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
export const decodeBase64Url = (str: string): Uint8Array => {
2-
return decodeBase64(str.replace(/_|-/g, (m) => ({ _: "/", "-": "+" }[m]!)))
2+
return decodeBase64(str.replace(/_|-/g, m => ({ _: '/', '-': '+' }[m] ?? m)));
33
};
44

55
export const encodeBase64Url = (buf: ArrayBufferLike): string =>
6-
encodeBase64(buf).replace(/\/|\+/g, (m) => ({ "/": "_", "+": "-" }[m]!));
6+
encodeBase64(buf).replace(/\/|\+/g, m => ({ '/': '_', '+': '-' }[m] ?? m));
77

88
// This approach is written in MDN.
99
// btoa does not support utf-8 characters. So we need a little bit hack.
1010
export const encodeBase64 = (buf: ArrayBufferLike): string => {
11-
const binary = String.fromCharCode(...new Uint8Array(buf))
12-
return btoa(binary)
13-
}
11+
const binary = String.fromCharCode(...new Uint8Array(buf));
12+
return btoa(binary);
13+
};
1414

1515
// atob does not support utf-8 characters. So we need a little bit hack.
1616
const decodeBase64 = (str: string): Uint8Array => {
17-
const binary = atob(str)
17+
const binary = atob(str);
1818
const bytes = new Uint8Array(new ArrayBuffer(binary.length));
1919
const half = binary.length / 2;
2020
for (let i = 0, j = binary.length - 1; i <= half; i++, j--) {
2121
bytes[i] = binary.charCodeAt(i);
2222
bytes[j] = binary.charCodeAt(j);
2323
}
24-
return bytes
25-
}
24+
return bytes;
25+
};

src/emulator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export interface EmulatorEnv {
2-
FIREBASE_AUTH_EMULATOR_HOST: string | undefined
2+
FIREBASE_AUTH_EMULATOR_HOST: string | undefined;
33
}
44

55
export function emulatorHost(env?: EmulatorEnv): string | undefined {

src/errors.ts

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,54 +16,53 @@ export class JwtError extends Error {
1616
* JWT error codes.
1717
*/
1818
export enum JwtErrorCode {
19-
INVALID_ARGUMENT = "invalid-argument",
20-
INVALID_CREDENTIAL = "invalid-credential",
21-
TOKEN_EXPIRED = "token-expired",
22-
INVALID_SIGNATURE = "invalid-token",
23-
NO_MATCHING_KID = "no-matching-kid-error",
24-
NO_KID_IN_HEADER = "no-kid-error",
25-
KEY_FETCH_ERROR = "key-fetch-error",
19+
INVALID_ARGUMENT = 'invalid-argument',
20+
INVALID_CREDENTIAL = 'invalid-credential',
21+
TOKEN_EXPIRED = 'token-expired',
22+
INVALID_SIGNATURE = 'invalid-token',
23+
NO_MATCHING_KID = 'no-matching-kid-error',
24+
NO_KID_IN_HEADER = 'no-kid-error',
25+
KEY_FETCH_ERROR = 'key-fetch-error',
2626
}
2727

2828
/**
2929
* App client error codes and their default messages.
3030
*/
3131
export class AppErrorCodes {
32-
public static INVALID_CREDENTIAL = "invalid-credential";
32+
public static INVALID_CREDENTIAL = 'invalid-credential';
3333
}
3434

3535
/**
3636
* Auth client error codes and their default messages.
3737
*/
3838
export class AuthClientErrorCode {
3939
public static INVALID_ARGUMENT = {
40-
code: "argument-error",
41-
message: "Invalid argument provided.",
40+
code: 'argument-error',
41+
message: 'Invalid argument provided.',
4242
};
4343
public static INVALID_CREDENTIAL = {
44-
code: "invalid-credential",
45-
message: "Invalid credential object provided.",
44+
code: 'invalid-credential',
45+
message: 'Invalid credential object provided.',
4646
};
4747
public static ID_TOKEN_EXPIRED = {
48-
code: "id-token-expired",
49-
message: "The provided Firebase ID token is expired.",
48+
code: 'id-token-expired',
49+
message: 'The provided Firebase ID token is expired.',
5050
};
5151
public static ID_TOKEN_REVOKED = {
52-
code: "id-token-revoked",
53-
message: "The Firebase ID token has been revoked.",
52+
code: 'id-token-revoked',
53+
message: 'The Firebase ID token has been revoked.',
5454
};
5555
public static INTERNAL_ERROR = {
56-
code: "internal-error",
57-
message: "An internal error has occurred.",
56+
code: 'internal-error',
57+
message: 'An internal error has occurred.',
5858
};
5959
public static USER_NOT_FOUND = {
60-
code: "user-not-found",
61-
message:
62-
"There is no user record corresponding to the provided identifier.",
60+
code: 'user-not-found',
61+
message: 'There is no user record corresponding to the provided identifier.',
6362
};
6463
public static USER_DISABLED = {
65-
code: "user-disabled",
66-
message: "The user record is disabled.",
64+
code: 'user-disabled',
65+
message: 'The user record is disabled.',
6766
};
6867
}
6968

@@ -197,7 +196,7 @@ export class PrefixedFirebaseError extends FirebaseError {
197196
export class FirebaseAuthError extends PrefixedFirebaseError {
198197
constructor(info: ErrorInfo, message?: string) {
199198
// Override default message if custom message provided.
200-
super("auth", info.code, message || info.message);
199+
super('auth', info.code, message || info.message);
201200

202201
/* tslint:disable:max-line-length */
203202
// Set the prototype explicitly. See the following link for more details:

0 commit comments

Comments
 (0)