## @strpc 기존 RPC를 package화 ### @strpc/express express의 middleware + router 결함 ## @sammo 게임 전체 - server, client - gateway_server, gateway_client
73 lines
2.6 KiB
TypeScript
73 lines
2.6 KiB
TypeScript
import type { WrappedBuffer } from "@sammo/util";
|
|
|
|
const crypto = globalThis.crypto;
|
|
|
|
export function randomBytes(length: number): Buffer {
|
|
const buffer = Buffer.alloc(length);
|
|
crypto.getRandomValues(buffer);
|
|
return buffer;
|
|
}
|
|
|
|
//TODO: 필요할때마다 확장
|
|
export type ValidPEMType = 'PUBLIC KEY' | 'EC PRIVATE KEY' | 'CERTIFICATE';
|
|
|
|
/**
|
|
* PEM string에 내부 타입으로 WrappedBuffer를 보관한 형태
|
|
*/
|
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
export type PEMString<T extends Buffer, S extends ValidPEMType> = string & {
|
|
/** 타입구분자. 항상 undefined일 것이다 */
|
|
_pem_b_type?: T;
|
|
_pem_type?: S;
|
|
}
|
|
|
|
export function encodePEM<T extends WrappedBuffer, S extends ValidPEMType>(data: T, pemType: S): PEMString<T, S>;
|
|
export function encodePEM(data: Buffer, pemType: ValidPEMType): string;
|
|
export function encodePEM(data: Buffer, pemType: ValidPEMType): string {
|
|
const base64text = data.toString('base64');
|
|
const splitText = base64text.match(/.{1,64}/g)?.join('\n') ?? '';
|
|
|
|
return `-----BEGIN ${pemType}-----
|
|
${splitText}
|
|
-----END ${pemType}-----
|
|
`;
|
|
}
|
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
type InferPEMType<T extends PEMString<any, any>> = Exclude<undefined, T['_pem_type']>;
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
type InferPEMBuffer<T extends PEMString<any, any>> = Exclude<undefined, T['_pem_b_type']>;
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
export function decodePEM<T extends PEMString<any, any>>(pem: T, pemType: InferPEMType<T>): InferPEMBuffer<T>[];
|
|
export function decodePEM(pem: string, pemType?: ValidPEMType): Buffer[];
|
|
export function decodePEM(pem: string, pemType?: ValidPEMType): Buffer[] {
|
|
const tag = pemType ?? "[A-Z0-9 ]+";
|
|
const pattern = new RegExp(`-{5}BEGIN ${tag}-{5}([a-zA-Z0-9=+\\/\\n\\r]+)-{5}END ${tag}-{5}`, "g");
|
|
|
|
const res: Buffer[] = [];
|
|
let matches: RegExpExecArray | null = null;
|
|
// eslint-disable-next-line no-cond-assign
|
|
while (matches = pattern.exec(pem)) {
|
|
const base64 = matches[1]
|
|
.replace(/\r/g, "")
|
|
.replace(/\n/g, "");
|
|
res.push(Buffer.from(base64, 'base64'));
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
export function decodeSinglePEM<T extends PEMString<any, any>>(pem: T, pemType: InferPEMType<T>): InferPEMBuffer<T>;
|
|
export function decodeSinglePEM(pem: string, pemType?: ValidPEMType): Buffer;
|
|
export function decodeSinglePEM(pem: string, pemType?: ValidPEMType): Buffer {
|
|
const res = decodePEM(pem, pemType);
|
|
if (res.length != 1) {
|
|
throw new Error("invalid pem");
|
|
}
|
|
return res[0];
|
|
} |