Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 1x | import "../../../configEnv";
import { ITokenService } from "@schemas/services/token/token.v1.service";
import Knex from "knex";
import knexfile from "@services/user/knexfile";
import { loadModels } from "@lib/objection-utils/objection-utils.lib";
import path from "path";
import {
AuthReq,
AuthRsp,
IssueReq,
IssueRsp,
RefreshReq,
RefreshRsp,
RevokeReq,
RevokeRsp,
} from "@schemas/services/token/token.v1.schemas";
import UserToken from "@services/user/models/UserToken.model";
import { uniqueString } from "@lib/encryption/encryption.lib";
import { UserTokenExpired, UserTokenNotFound } from "@services/user/errors/token.errors";
import _ from "lodash";
export default class TokenService implements ITokenService {
async init(): Promise<void> {
const masterKnex = Knex(knexfile.production);
const slaveKnex = Knex(knexfile.slave);
loadModels(masterKnex, slaveKnex, path.join(__dirname, "models"));
}
async Auth(ctx, req: AuthReq): Promise<AuthRsp> {
const { accessToken } = req;
const token = await UserToken.query()
.where({
accessToken,
})
.select(["id", "userId"])
.limit(1)
.first();
if (!token) {
throw new UserTokenNotFound({
accessToken,
});
}
return {
id: token.id,
userId: token.userId,
};
}
async Issue(ctx, req: IssueReq): Promise<IssueRsp> {
const { userId, type, scope, appId, meta } = req;
const accessToken = await this.newAccessToken();
const refreshToken = await this.newRefreshToken();
await UserToken.queryOnMaster().insert({
userId,
type,
accessToken,
refreshToken,
scope: JSON.stringify(scope),
appId,
meta: JSON.stringify(meta),
expiresAt: new Date(Date.now() + 3600000),
});
return { accessToken, refreshToken, expiresIn: 3600 };
}
async Refresh(ctx, req: RefreshReq): Promise<RefreshRsp> {
const { refreshToken } = req;
const token = await UserToken.query()
.where({
refreshToken,
})
.select("id", "expiresAt")
.limit(1)
.first();
Iif (!token) {
throw new UserTokenNotFound({
refreshToken,
});
}
if (Date.now() > token.expiresAt.getTime()) {
throw new UserTokenExpired(token.expiresAt);
}
token.accessToken = await this.newAccessToken();
token.expiresAt = new Date(Date.now() + 3600000);
await token.$queryOnMaster().patch(_.pick(token, ["accessToken", "expiresAt"]));
return {
accessToken: token.accessToken,
expiresIn: 3600,
};
}
async Revoke(ctx, req: RevokeReq): Promise<RevokeRsp> {
// @ts-ignore
const { id, refreshToken, accessToken } = req;
const query = UserToken.queryOnMaster();
Iif (id) {
query.where({
id,
});
} else Eif (refreshToken) {
query.where({
refreshToken,
});
} else if (accessToken) {
query.where({
accessToken,
});
} else {
throw new Error("bad request");
}
await query.delete();
return {};
}
async newAccessToken(): Promise<string> {
return uniqueString(32);
}
async newRefreshToken(): Promise<string> {
return uniqueString(64);
}
}
|