Skip to content

Commit e5ba2ee

Browse files
authored
Merge pull request #8 from cobuildlab/feature/auth0-class-extend
add extends class implementation
2 parents a498c91 + dc318e9 commit e5ba2ee

File tree

8 files changed

+254
-245
lines changed

8 files changed

+254
-245
lines changed

src/client.ts

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import Auth0, {
2+
AuthorizeOptions,
3+
Credentials as Auth0Credentials,
4+
Options,
5+
} from 'react-native-auth0';
6+
import { Credentials, CredentialsHandlersInput, ErrorCases } from './types';
7+
import { ErrorPublisher, getTimestamp } from './utils';
8+
9+
export class Auth0Native extends Auth0 {
10+
private credentials: Credentials | null = null;
11+
12+
private saveCredentials: CredentialsHandlersInput['save'];
13+
14+
private getCredentials: CredentialsHandlersInput['get'];
15+
16+
private clearCredentials: CredentialsHandlersInput['clear'];
17+
18+
private errors: Record<ErrorCases, ErrorPublisher> = {
19+
AUTHORIZATION: new ErrorPublisher(),
20+
CLEAR_SESSION: new ErrorPublisher(),
21+
REFRESH_TOKEN: new ErrorPublisher(),
22+
};
23+
24+
constructor(options: Options, credentialsHandlers: CredentialsHandlersInput) {
25+
super(options);
26+
this.saveCredentials = credentialsHandlers.save;
27+
this.getCredentials = credentialsHandlers.get;
28+
this.clearCredentials = credentialsHandlers.clear;
29+
}
30+
31+
async handleCredentials(data: Auth0Credentials): Promise<Credentials> {
32+
const credentials: Credentials = { ...data, issuedAt: getTimestamp() };
33+
34+
await this.saveCredentials(credentials);
35+
36+
this.credentials = credentials;
37+
38+
return credentials;
39+
}
40+
41+
getAuthInfo(): Credentials | null {
42+
return this.credentials;
43+
}
44+
45+
/**
46+
*
47+
* @param {string} scope - Scopes requested for the issued tokens. E.g. `openid profile`.
48+
* @param {object} options - Options to pass to the auth endpoint.
49+
* @returns {object} The auth0 credentials.
50+
*/
51+
async authorize(
52+
scope: string,
53+
options: AuthorizeOptions = {},
54+
): Promise<Credentials | undefined> {
55+
try {
56+
const result = await this.webAuth.authorize(
57+
{
58+
scope,
59+
},
60+
options,
61+
);
62+
63+
return this.handleCredentials(result);
64+
} catch (error) {
65+
this.errors.AUTHORIZATION.notify(error as Error);
66+
return;
67+
}
68+
}
69+
70+
async clearSession(): Promise<void> {
71+
this.credentials = null;
72+
73+
try {
74+
this.webAuth.clearSession();
75+
} catch (error) {
76+
this.errors.CLEAR_SESSION.notify(error as Error);
77+
}
78+
79+
await this.clearCredentials();
80+
}
81+
82+
async isAuthenticated(): Promise<boolean> {
83+
const credentials = this.credentials || (await this.getCredentials());
84+
85+
if (!credentials) {
86+
return false;
87+
}
88+
89+
const tokenTimestamp = credentials.expiresIn + credentials.issuedAt;
90+
91+
const validToken = tokenTimestamp > getTimestamp();
92+
93+
if (validToken) {
94+
this.credentials = credentials;
95+
return true;
96+
}
97+
98+
if (credentials.refreshToken) {
99+
try {
100+
const newCredentials = await this.auth.refreshToken({
101+
refreshToken: credentials.refreshToken,
102+
});
103+
104+
await this.handleCredentials({
105+
...newCredentials,
106+
scope: credentials.scope,
107+
});
108+
109+
return true;
110+
} catch (error) {
111+
this.errors.REFRESH_TOKEN.notify(error as Error);
112+
return false;
113+
}
114+
}
115+
116+
return false;
117+
}
118+
}

src/constant.ts

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/context.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1-
/* eslint-disable @typescript-eslint/no-empty-function */
2-
import * as React from 'react';
3-
import { UseAuthType } from './types';
1+
import { createContext, useContext } from 'react';
2+
import { AuthClientContextType } from './types';
43

5-
export const AuthContext = React.createContext<UseAuthType>({
4+
/**
5+
* @ignore
6+
*/
7+
const stub = (): never => {
8+
throw new Error('You forgot to wrap your component in <Auth0Provider>.');
9+
};
10+
11+
export const AuthClientContext = createContext<AuthClientContextType>({
612
isAuthenticated: false,
7-
isLoading: false,
8-
login: () => {},
9-
logout: () => {},
13+
isLoading: true,
14+
clearSession: stub,
15+
authorize: stub,
1016
});
1117

12-
18+
export const useAuth = (): AuthClientContextType =>
19+
useContext(AuthClientContext);

src/hook.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import * as React from 'react';
2-
import { UseAuthType } from './types';
3-
import { AuthContext } from './context';
1+
import { useContext } from 'react';
42

5-
export const useAuth = (): UseAuthType => {
6-
const context = React.useContext(AuthContext);
7-
return context;
8-
};
3+
import { AuthClientContext } from './context';
4+
import { AuthClientContextType } from './types';
5+
6+
export const useAuth = (): AuthClientContextType =>
7+
useContext(AuthClientContext);

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './hook';
22
export * from './provider';
3-
export * from './types';
3+
export * from './types';
4+
export * from './client';

0 commit comments

Comments
 (0)