Repository navigation
Expand file tree
/
Copy pathFileTokenStorage.ts
More file actions
72 lines (61 loc) · 1.97 KB
/
Copy pathFileTokenStorage.ts
File metadata and controls
72 lines (61 loc) · 1.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import { promises as fs } from 'fs';
import { join } from 'path';
import { OAuth2Error } from '../../common/errors';
import { TokenStorageProvider } from './types';
import { TokenData } from './types';
export class FileTokenStorage implements TokenStorageProvider {
private readonly tokenFilePath: string;
private readonly serviceName: string;
constructor(serviceName: string = 'qbo', tokenFilePath?: string) {
this.serviceName = serviceName;
this.tokenFilePath =
tokenFilePath ||
join(process.cwd(), 'data', 'oauth2_tokens', `${serviceName}.json`);
}
async save(tokenData: TokenData): Promise<void> {
try {
const dir = join(this.tokenFilePath, '..');
await fs.mkdir(dir, { recursive: true });
await fs.writeFile(
this.tokenFilePath,
JSON.stringify(tokenData, null, 2),
);
} catch {
throw new OAuth2Error('Failed to save token data to file');
}
}
async load(): Promise<TokenData | null> {
try {
const data = await fs.readFile(this.tokenFilePath, 'utf8');
const tokenData = JSON.parse(data) as TokenData;
if (!this.isValidTokenData(tokenData)) {
return null;
}
return tokenData;
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
return null;
}
return null;
}
}
async clear(): Promise<void> {
try {
await fs.unlink(this.tokenFilePath);
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {
throw new OAuth2Error('Failed to clear token data from file');
}
}
}
private isValidTokenData(data: unknown): data is TokenData {
return (
typeof data === 'object' &&
data !== null &&
typeof (data as TokenData).access_token === 'string' &&
typeof (data as TokenData).refresh_token === 'string' &&
typeof (data as TokenData).expires_at === 'number' &&
typeof (data as TokenData).token_type === 'string'
);
}
}