This commit is contained in:
2025-11-11 00:04:55 -06:00
parent a76ad41fde
commit 40538eddfd
6405 changed files with 1289756 additions and 0 deletions

49
build/push/client.d.ts vendored Normal file
View File

@ -0,0 +1,49 @@
import { TypedEmitter } from "tiny-typed-emitter";
import { PushClientEvents } from "./interfaces";
export declare class PushClient extends TypedEmitter<PushClientEvents> {
private readonly HOST;
private readonly PORT;
private readonly MCS_VERSION;
private readonly HEARTBEAT_INTERVAL;
private loggedIn;
private streamId;
private lastStreamIdReported;
private currentDelay;
private client?;
private heartbeatTimeout?;
private reconnectTimeout?;
private persistentIds;
private static proto;
private pushClientParser;
private auth;
private constructor();
static init(auth: {
androidId: string;
securityToken: string;
}): Promise<PushClient>;
private initialize;
getPersistentIds(): Array<string>;
setPersistentIds(ids: Array<string>): void;
connect(): void;
private buildLoginRequest;
private buildHeartbeatPingRequest;
private buildHeartbeatAckRequest;
private onSocketData;
private onSocketConnect;
private onSocketClose;
private onSocketError;
private handleParsedMessage;
private handleHeartbeatPing;
private handleHeartbeatAck;
private convertPayloadMessage;
private getStreamId;
private newStreamIdAvailable;
private scheduleHeartbeat;
private sendHeartbeat;
isConnected(): boolean;
private getHeartbeatInterval;
private getCurrentDelay;
private resetCurrentDelay;
private scheduleReconnect;
close(): void;
}

323
build/push/client.js Normal file
View File

@ -0,0 +1,323 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PushClient = void 0;
const long_1 = __importDefault(require("long"));
const path = __importStar(require("path"));
const protobufjs_1 = require("protobufjs");
const tls = __importStar(require("tls"));
const tiny_typed_emitter_1 = require("tiny-typed-emitter");
const models_1 = require("./models");
const parser_1 = require("./parser");
const utils_1 = require("../utils");
const error_1 = require("./error");
const error_2 = require("../error");
const utils_2 = require("../p2p/utils");
const logging_1 = require("../logging");
class PushClient extends tiny_typed_emitter_1.TypedEmitter {
HOST = "mtalk.google.com";
PORT = 5228;
MCS_VERSION = 41;
HEARTBEAT_INTERVAL = 5 * 60 * 1000;
loggedIn = false;
streamId = 0;
lastStreamIdReported = -1;
currentDelay = 0;
client;
heartbeatTimeout;
reconnectTimeout;
persistentIds = [];
static proto = null;
pushClientParser;
auth;
constructor(pushClientParser, auth) {
super();
this.pushClientParser = pushClientParser;
this.auth = auth;
}
static async init(auth) {
this.proto = await (0, protobufjs_1.load)(path.join(__dirname, "./proto/mcs.proto"));
const pushClientParser = await parser_1.PushClientParser.init();
return new PushClient(pushClientParser, auth);
}
initialize() {
this.loggedIn = false;
this.streamId = 0;
this.lastStreamIdReported = -1;
if (this.client) {
this.client.removeAllListeners();
this.client.destroy();
this.client = undefined;
}
this.pushClientParser.resetState();
if (this.reconnectTimeout) {
clearTimeout(this.reconnectTimeout);
this.reconnectTimeout = undefined;
}
}
getPersistentIds() {
return this.persistentIds;
}
setPersistentIds(ids) {
this.persistentIds = ids;
}
connect() {
this.initialize();
this.pushClientParser.on("message", (message) => this.handleParsedMessage(message));
this.client = tls.connect(this.PORT, this.HOST, {
rejectUnauthorized: false,
});
this.client.setKeepAlive(true);
// For debugging purposes
//this.client.enableTrace();
this.client.on("connect", () => this.onSocketConnect());
this.client.on("close", () => this.onSocketClose());
this.client.on("error", (error) => this.onSocketError(error));
this.client.on("data", (newData) => this.onSocketData(newData));
this.client.write(this.buildLoginRequest());
}
buildLoginRequest() {
const androidId = this.auth.androidId;
const securityToken = this.auth.securityToken;
const LoginRequestType = PushClient.proto.lookupType("mcs_proto.LoginRequest");
const hexAndroidId = long_1.default.fromString(androidId).toString(16);
const loginRequest = {
adaptiveHeartbeat: false,
authService: 2,
authToken: securityToken,
id: "chrome-63.0.3234.0",
domain: "mcs.android.com",
deviceId: `android-${hexAndroidId}`,
networkType: 1,
resource: androidId,
user: androidId,
useRmq2: true,
setting: [{ name: "new_vc", value: "1" }],
clientEvent: [],
receivedPersistentId: this.persistentIds,
};
const errorMessage = LoginRequestType.verify(loginRequest);
if (errorMessage) {
throw new error_1.BuildLoginRequestError(errorMessage, { context: { loginRequest: loginRequest } });
}
const buffer = LoginRequestType.encodeDelimited(loginRequest).finish();
return Buffer.concat([Buffer.from([this.MCS_VERSION, models_1.MessageTag.LoginRequest]), buffer]);
}
buildHeartbeatPingRequest(stream_id) {
const heartbeatPingRequest = {};
if (stream_id) {
heartbeatPingRequest.last_stream_id_received = stream_id;
}
logging_1.rootPushLogger.debug(`Push client - heartbeatPingRequest`, { streamId: stream_id, request: JSON.stringify(heartbeatPingRequest) });
const HeartbeatPingRequestType = PushClient.proto.lookupType("mcs_proto.HeartbeatPing");
const errorMessage = HeartbeatPingRequestType.verify(heartbeatPingRequest);
if (errorMessage) {
throw new error_1.BuildHeartbeatPingRequestError(errorMessage, { context: { heartbeatPingRequest: heartbeatPingRequest } });
}
const buffer = HeartbeatPingRequestType.encodeDelimited(heartbeatPingRequest).finish();
return Buffer.concat([Buffer.from([models_1.MessageTag.HeartbeatPing]), buffer]);
}
buildHeartbeatAckRequest(stream_id, status) {
const heartbeatAckRequest = {};
if (stream_id && !status) {
heartbeatAckRequest.last_stream_id_received = stream_id;
}
else if (!stream_id && status) {
heartbeatAckRequest.status = status;
}
else {
heartbeatAckRequest.last_stream_id_received = stream_id;
heartbeatAckRequest.status = status;
}
logging_1.rootPushLogger.debug(`Push client - heartbeatAckRequest`, { streamId: stream_id, status: status, request: JSON.stringify(heartbeatAckRequest) });
const HeartbeatAckRequestType = PushClient.proto.lookupType("mcs_proto.HeartbeatAck");
const errorMessage = HeartbeatAckRequestType.verify(heartbeatAckRequest);
if (errorMessage) {
throw new error_1.BuildHeartbeatAckRequestError(errorMessage, { context: { heartbeatAckRequest: heartbeatAckRequest } });
}
const buffer = HeartbeatAckRequestType.encodeDelimited(heartbeatAckRequest).finish();
return Buffer.concat([Buffer.from([models_1.MessageTag.HeartbeatAck]), buffer]);
}
onSocketData(newData) {
this.pushClientParser.handleData(newData);
}
onSocketConnect() {
//
}
onSocketClose() {
this.loggedIn = false;
if (this.heartbeatTimeout) {
clearTimeout(this.heartbeatTimeout);
this.heartbeatTimeout = undefined;
}
this.emit("close");
this.scheduleReconnect();
}
onSocketError(err) {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error(`Push client - Socket Error`, { error: (0, utils_1.getError)(error) });
}
handleParsedMessage(message) {
this.resetCurrentDelay();
switch (message.tag) {
case models_1.MessageTag.DataMessageStanza:
logging_1.rootPushLogger.debug(`Push client - DataMessageStanza`, { message: JSON.stringify(message) });
if (message.object && message.object.persistentId)
this.persistentIds.push(message.object.persistentId);
this.emit("message", this.convertPayloadMessage(message));
break;
case models_1.MessageTag.HeartbeatPing:
this.handleHeartbeatPing(message);
break;
case models_1.MessageTag.HeartbeatAck:
this.handleHeartbeatAck(message);
break;
case models_1.MessageTag.Close:
logging_1.rootPushLogger.debug(`Push client - Close: Server requested close`, { message: JSON.stringify(message) });
break;
case models_1.MessageTag.LoginResponse:
logging_1.rootPushLogger.debug("Push client - Login response: GCM -> logged in -> waiting for push messages...", { message: JSON.stringify(message) });
this.loggedIn = true;
this.persistentIds = [];
this.emit("connect");
this.heartbeatTimeout = setTimeout(() => {
this.scheduleHeartbeat(this);
}, this.getHeartbeatInterval());
break;
case models_1.MessageTag.LoginRequest:
logging_1.rootPushLogger.debug(`Push client - Login request`, { message: JSON.stringify(message) });
break;
case models_1.MessageTag.IqStanza:
logging_1.rootPushLogger.debug(`Push client - IqStanza: Not implemented`, { message: JSON.stringify(message) });
break;
default:
logging_1.rootPushLogger.debug(`Push client - Unknown message`, { message: JSON.stringify(message) });
return;
}
this.streamId++;
}
handleHeartbeatPing(message) {
logging_1.rootPushLogger.debug(`Push client - Heartbeat ping`, { message: JSON.stringify(message) });
let streamId = undefined;
let status = undefined;
if (this.newStreamIdAvailable()) {
streamId = this.getStreamId();
}
if (message.object && message.object.status) {
status = message.object.status;
}
if (this.client)
this.client.write(this.buildHeartbeatAckRequest(streamId, status));
}
handleHeartbeatAck(message) {
logging_1.rootPushLogger.debug(`Push client - Heartbeat acknowledge`, { message: JSON.stringify(message) });
}
convertPayloadMessage(message) {
const { appData, ...otherData } = message.object;
const messageData = {};
appData.forEach((kv) => {
if (kv.key === "payload") {
const payload = (0, utils_1.parseJSON)((0, utils_2.getNullTerminatedString)(Buffer.from(kv.value, "base64"), "utf8"), logging_1.rootPushLogger);
messageData[kv.key] = payload;
}
else {
messageData[kv.key] = kv.value;
}
});
return {
...otherData,
payload: messageData,
};
}
getStreamId() {
this.lastStreamIdReported = this.streamId;
return this.streamId;
}
newStreamIdAvailable() {
return this.lastStreamIdReported != this.streamId;
}
scheduleHeartbeat(client) {
if (client.sendHeartbeat()) {
this.heartbeatTimeout = setTimeout(() => {
this.scheduleHeartbeat(client);
}, client.getHeartbeatInterval());
}
else {
logging_1.rootPushLogger.debug("Push client - Heartbeat disabled!");
}
}
sendHeartbeat() {
let streamId = undefined;
if (this.newStreamIdAvailable()) {
streamId = this.getStreamId();
}
if (this.client && this.isConnected()) {
logging_1.rootPushLogger.debug(`Push client - Sending heartbeat...`, { streamId: streamId });
this.client.write(this.buildHeartbeatPingRequest(streamId));
return true;
}
else {
logging_1.rootPushLogger.debug("Push client - No more connected, reconnect...");
this.scheduleReconnect();
}
return false;
}
isConnected() {
return this.loggedIn;
}
getHeartbeatInterval() {
return this.HEARTBEAT_INTERVAL;
}
getCurrentDelay() {
const delay = this.currentDelay == 0 ? 5000 : this.currentDelay;
if (this.currentDelay < 60000)
this.currentDelay += 10000;
if (this.currentDelay >= 60000 && this.currentDelay < 600000)
this.currentDelay += 60000;
return delay;
}
resetCurrentDelay() {
this.currentDelay = 0;
}
scheduleReconnect() {
const delay = this.getCurrentDelay();
logging_1.rootPushLogger.debug("Push client - Schedule reconnect...", { delay: delay });
if (!this.reconnectTimeout)
this.reconnectTimeout = setTimeout(() => {
this.connect();
}, delay);
}
close() {
const wasConnected = this.isConnected();
this.initialize();
if (wasConnected)
this.emit("close");
}
}
exports.PushClient = PushClient;
//# sourceMappingURL=client.js.map

1
build/push/client.js.map Normal file

File diff suppressed because one or more lines are too long

73
build/push/error.d.ts vendored Normal file
View File

@ -0,0 +1,73 @@
import { BaseError, Jsonable } from "../error";
export declare class UnknownExpiryFormaError extends BaseError {
constructor(message: string, options?: {
cause?: Error;
context?: Jsonable;
});
}
export declare class FidRegistrationFailedError extends BaseError {
constructor(message: string, options?: {
cause?: Error;
context?: Jsonable;
});
}
export declare class RenewFidTokenFailedError extends BaseError {
constructor(message: string, options?: {
cause?: Error;
context?: Jsonable;
});
}
export declare class ExecuteCheckInError extends BaseError {
constructor(message: string, options?: {
cause?: Error;
context?: Jsonable;
});
}
export declare class RegisterGcmError extends BaseError {
constructor(message: string, options?: {
cause?: Error;
context?: Jsonable;
});
}
export declare class BuildLoginRequestError extends BaseError {
constructor(message: string, options?: {
cause?: Error;
context?: Jsonable;
});
}
export declare class BuildHeartbeatPingRequestError extends BaseError {
constructor(message: string, options?: {
cause?: Error;
context?: Jsonable;
});
}
export declare class BuildHeartbeatAckRequestError extends BaseError {
constructor(message: string, options?: {
cause?: Error;
context?: Jsonable;
});
}
export declare class FidGenerationError extends BaseError {
constructor(message: string, options?: {
cause?: Error;
context?: Jsonable;
});
}
export declare class MCSProtocolVersionError extends BaseError {
constructor(message: string, options?: {
cause?: Error;
context?: Jsonable;
});
}
export declare class MCSProtocolProcessingStateError extends BaseError {
constructor(message: string, options?: {
cause?: Error;
context?: Jsonable;
});
}
export declare class MCSProtocolMessageTagError extends BaseError {
constructor(message: string, options?: {
cause?: Error;
context?: Jsonable;
});
}

101
build/push/error.js Normal file
View File

@ -0,0 +1,101 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MCSProtocolMessageTagError = exports.MCSProtocolProcessingStateError = exports.MCSProtocolVersionError = exports.FidGenerationError = exports.BuildHeartbeatAckRequestError = exports.BuildHeartbeatPingRequestError = exports.BuildLoginRequestError = exports.RegisterGcmError = exports.ExecuteCheckInError = exports.RenewFidTokenFailedError = exports.FidRegistrationFailedError = exports.UnknownExpiryFormaError = void 0;
const error_1 = require("../error");
class UnknownExpiryFormaError extends error_1.BaseError {
constructor(message, options = {}) {
super(message, options);
Object.setPrototypeOf(this, new.target.prototype);
this.name = UnknownExpiryFormaError.name;
}
}
exports.UnknownExpiryFormaError = UnknownExpiryFormaError;
class FidRegistrationFailedError extends error_1.BaseError {
constructor(message, options = {}) {
super(message, options);
Object.setPrototypeOf(this, new.target.prototype);
this.name = FidRegistrationFailedError.name;
}
}
exports.FidRegistrationFailedError = FidRegistrationFailedError;
class RenewFidTokenFailedError extends error_1.BaseError {
constructor(message, options = {}) {
super(message, options);
Object.setPrototypeOf(this, new.target.prototype);
this.name = RenewFidTokenFailedError.name;
}
}
exports.RenewFidTokenFailedError = RenewFidTokenFailedError;
class ExecuteCheckInError extends error_1.BaseError {
constructor(message, options = {}) {
super(message, options);
Object.setPrototypeOf(this, new.target.prototype);
this.name = ExecuteCheckInError.name;
}
}
exports.ExecuteCheckInError = ExecuteCheckInError;
class RegisterGcmError extends error_1.BaseError {
constructor(message, options = {}) {
super(message, options);
Object.setPrototypeOf(this, new.target.prototype);
this.name = RegisterGcmError.name;
}
}
exports.RegisterGcmError = RegisterGcmError;
class BuildLoginRequestError extends error_1.BaseError {
constructor(message, options = {}) {
super(message, options);
Object.setPrototypeOf(this, new.target.prototype);
this.name = BuildLoginRequestError.name;
}
}
exports.BuildLoginRequestError = BuildLoginRequestError;
class BuildHeartbeatPingRequestError extends error_1.BaseError {
constructor(message, options = {}) {
super(message, options);
Object.setPrototypeOf(this, new.target.prototype);
this.name = BuildHeartbeatPingRequestError.name;
}
}
exports.BuildHeartbeatPingRequestError = BuildHeartbeatPingRequestError;
class BuildHeartbeatAckRequestError extends error_1.BaseError {
constructor(message, options = {}) {
super(message, options);
Object.setPrototypeOf(this, new.target.prototype);
this.name = BuildHeartbeatAckRequestError.name;
}
}
exports.BuildHeartbeatAckRequestError = BuildHeartbeatAckRequestError;
class FidGenerationError extends error_1.BaseError {
constructor(message, options = {}) {
super(message, options);
Object.setPrototypeOf(this, new.target.prototype);
this.name = FidGenerationError.name;
}
}
exports.FidGenerationError = FidGenerationError;
class MCSProtocolVersionError extends error_1.BaseError {
constructor(message, options = {}) {
super(message, options);
Object.setPrototypeOf(this, new.target.prototype);
this.name = MCSProtocolVersionError.name;
}
}
exports.MCSProtocolVersionError = MCSProtocolVersionError;
class MCSProtocolProcessingStateError extends error_1.BaseError {
constructor(message, options = {}) {
super(message, options);
Object.setPrototypeOf(this, new.target.prototype);
this.name = MCSProtocolProcessingStateError.name;
}
}
exports.MCSProtocolProcessingStateError = MCSProtocolProcessingStateError;
class MCSProtocolMessageTagError extends error_1.BaseError {
constructor(message, options = {}) {
super(message, options);
Object.setPrototypeOf(this, new.target.prototype);
this.name = MCSProtocolMessageTagError.name;
}
}
exports.MCSProtocolMessageTagError = MCSProtocolMessageTagError;
//# sourceMappingURL=error.js.map

1
build/push/error.js.map Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/push/error.ts"],"names":[],"mappings":";;;AAAA,oCAA+C;AAE/C,MAAa,uBAAwB,SAAQ,iBAAS;IAClD,YAAY,OAAe,EAAE,UAAiD,EAAE;QAC5E,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC,IAAI,CAAC;IAC7C,CAAC;CACJ;AAND,0DAMC;AAED,MAAa,0BAA2B,SAAQ,iBAAS;IACrD,YAAY,OAAe,EAAE,UAAiD,EAAE;QAC5E,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC,IAAI,CAAC;IAChD,CAAC;CACJ;AAND,gEAMC;AAED,MAAa,wBAAyB,SAAQ,iBAAS;IACnD,YAAY,OAAe,EAAE,UAAiD,EAAE;QAC5E,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC,IAAI,CAAC;IAC9C,CAAC;CACJ;AAND,4DAMC;AAED,MAAa,mBAAoB,SAAQ,iBAAS;IAC9C,YAAY,OAAe,EAAE,UAAiD,EAAE;QAC5E,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC;IACzC,CAAC;CACJ;AAND,kDAMC;AAED,MAAa,gBAAiB,SAAQ,iBAAS;IAC3C,YAAY,OAAe,EAAE,UAAiD,EAAE;QAC5E,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC;IACtC,CAAC;CACJ;AAND,4CAMC;AAED,MAAa,sBAAuB,SAAQ,iBAAS;IACjD,YAAY,OAAe,EAAE,UAAiD,EAAE;QAC5E,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC,IAAI,CAAC;IAC5C,CAAC;CACJ;AAND,wDAMC;AAED,MAAa,8BAA+B,SAAQ,iBAAS;IACzD,YAAY,OAAe,EAAE,UAAiD,EAAE;QAC5E,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC,IAAI,CAAC;IACpD,CAAC;CACJ;AAND,wEAMC;AAED,MAAa,6BAA8B,SAAQ,iBAAS;IACxD,YAAY,OAAe,EAAE,UAAiD,EAAE;QAC5E,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC,IAAI,CAAC;IACnD,CAAC;CACJ;AAND,sEAMC;AAED,MAAa,kBAAmB,SAAQ,iBAAS;IAC7C,YAAY,OAAe,EAAE,UAAiD,EAAE;QAC5E,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC;IACxC,CAAC;CACJ;AAND,gDAMC;AAED,MAAa,uBAAwB,SAAQ,iBAAS;IAClD,YAAY,OAAe,EAAE,UAAiD,EAAE;QAC5E,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC,IAAI,CAAC;IAC7C,CAAC;CACJ;AAND,0DAMC;AAED,MAAa,+BAAgC,SAAQ,iBAAS;IAC1D,YAAY,OAAe,EAAE,UAAiD,EAAE;QAC5E,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAC,IAAI,CAAC;IACrD,CAAC;CACJ;AAND,0EAMC;AAED,MAAa,0BAA2B,SAAQ,iBAAS;IACrD,YAAY,OAAe,EAAE,UAAiD,EAAE;QAC5E,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC,IAAI,CAAC;IAChD,CAAC;CACJ;AAND,gEAMC"}

6
build/push/index.d.ts vendored Normal file
View File

@ -0,0 +1,6 @@
export * from "./models";
export * from "./interfaces";
export * from "./service";
export * from "./types";
export * from "./error";
export { sleep, convertTimestampMs } from "./utils";

26
build/push/index.js Normal file
View File

@ -0,0 +1,26 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertTimestampMs = exports.sleep = void 0;
__exportStar(require("./models"), exports);
__exportStar(require("./interfaces"), exports);
__exportStar(require("./service"), exports);
__exportStar(require("./types"), exports);
__exportStar(require("./error"), exports);
var utils_1 = require("./utils");
Object.defineProperty(exports, "sleep", { enumerable: true, get: function () { return utils_1.sleep; } });
Object.defineProperty(exports, "convertTimestampMs", { enumerable: true, get: function () { return utils_1.convertTimestampMs; } });
//# sourceMappingURL=index.js.map

1
build/push/index.js.map Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/push/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,+CAA6B;AAC7B,4CAA0B;AAC1B,0CAAwB;AACxB,0CAAwB;AACxB,iCAAoD;AAA3C,8FAAA,KAAK,OAAA;AAAE,2GAAA,kBAAkB,OAAA"}

19
build/push/interfaces.d.ts vendored Normal file
View File

@ -0,0 +1,19 @@
import { Credentials, RawPushMessage, PushMessage } from "./models";
export interface PushNotificationServiceEvents {
"credential": (credentials: Credentials) => void;
"connect": (token: string) => void;
"close": () => void;
"raw message": (message: RawPushMessage) => void;
"message": (message: PushMessage) => void;
}
export interface PushClientEvents {
"connect": () => void;
"close": () => void;
"message": (message: RawPushMessage) => void;
}
export interface PushClientParserEvents {
"message": (message: {
tag: number;
object: any;
}) => void;
}

3
build/push/interfaces.js Normal file
View File

@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=interfaces.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../src/push/interfaces.ts"],"names":[],"mappings":""}

328
build/push/models.d.ts vendored Normal file
View File

@ -0,0 +1,328 @@
import { UserType } from "../http/types";
import { AlarmAction } from "./types";
export interface CusPushData {
a?: number;
alarm?: number;
alarm_delay?: number;
alarm_type?: number;
arming?: number;
automation_id?: number;
batt_powered?: number;
c?: number;
channel?: number;
click_action?: string;
create_time?: number;
device_name?: string;
e?: string;
event_time?: number;
event_type?: number;
f?: string;
i?: string;
j?: number;
k?: number;
cipher?: number;
m?: number;
mode?: number;
n?: string;
name?: string;
news_id?: number;
nick_name?: string;
notification_style?: number;
p?: string;
file_path?: string;
pic_url?: string;
push_count?: number;
s: string;
session_id?: string;
short_user_id?: string;
storage_type?: number;
t?: string;
tfcard?: number;
type?: number;
unique_id?: string;
user?: UserType;
user_id?: string;
user_name?: string;
bat_low?: string;
msg_type: number;
r?: string;
u?: string;
}
export interface EufyPushMessage {
content: string;
device_sn: string;
event_time: string;
payload?: CusPushData | IndoorPushData | ServerPushData | BatteryDoorbellPushData | LockPushData | SmartSafePushData | GarageDoorPushData | AlarmPushData;
push_time: string;
station_sn: string;
title: string;
type: string;
doorbell?: string;
"google.c.sender.id": string;
}
export interface SmartSafeEventValueDetail {
type: number;
action: number;
figure_id: number;
user_id: number;
name?: string;
}
export interface SmartSafePushData {
dev_name: string;
event_type: number;
event_time: number;
event_value: number | SmartSafeEventValueDetail;
}
export interface LockPushData {
event_type: number;
event_time: number;
short_user_id: string;
nick_name: string;
user_id: string;
device_name: string;
device_sn: string;
}
export interface GarageDoorPushData {
a: number;
msg_type: number;
event_type: number;
door_id: number;
user_name: string;
door_name: string;
pic_url: string;
file_path: string;
storage_type: number;
unique_id: string;
power?: number;
}
export interface BatteryDoorbellPushData {
name: string;
channel: number;
cipher: number;
create_time: number;
device_sn: string;
session_id: string;
event_type: number;
file_path: string;
pic_url: string;
push_count: number;
notification_style: number;
objects?: DoorbellPeopleNames;
nick_name?: string;
}
export interface DoorbellPeopleNames {
names: string[];
}
export interface RawPushMessage {
id: string;
from: string;
to: string;
category: string;
persistentId: string;
ttl: number;
sent: string;
payload: EufyPushMessage;
}
export interface FidTokenResponse {
token: string;
expiresIn: string;
expiresAt: number;
}
export interface FidInstallationResponse {
name: string;
fid: string;
refreshToken: string;
authToken: FidTokenResponse;
}
export interface CheckinResponse {
statsOk: boolean;
timeMs: string;
androidId: string;
securityToken: string;
versionInfo: string;
deviceDataVersionInfo: string;
}
export interface GcmRegisterResponse {
token: string;
}
export interface Message {
tag: number;
object: any;
}
export declare enum ProcessingState {
MCS_VERSION_TAG_AND_SIZE = 0,
MCS_TAG_AND_SIZE = 1,
MCS_SIZE = 2,
MCS_PROTO_BYTES = 3
}
export declare enum MessageTag {
HeartbeatPing = 0,
HeartbeatAck = 1,
LoginRequest = 2,
LoginResponse = 3,
Close = 4,
MessageStanza = 5,
PresenceStanza = 6,
IqStanza = 7,
DataMessageStanza = 8,
BatchPresenceStanza = 9,
StreamErrorStanza = 10,
HttpRequest = 11,
HttpResponse = 12,
BindAccountRequest = 13,
BindAccountResponse = 14,
TalkMetadata = 15,
NumProtoTypes = 16
}
export interface Credentials {
fidResponse: FidInstallationResponse;
checkinResponse: CheckinResponse;
gcmResponse: GcmRegisterResponse;
}
export interface DoorbellPushData {
campaign_name: string;
channel: number;
cipher: number;
content: string;
create_time: number;
device_sn: string;
event_session: string;
event_time: number;
event_type: number;
file_path: string;
person_name?: string;
outer_body: string;
outer_title: string;
pic_url: string;
push_count: number;
station_sn: string;
title: string;
url: string;
url_ex: string;
video_url: string;
}
export interface IndoorPushData {
a: number;
channel: number;
cipher: number;
create_time: number;
trigger_time: number;
device_sn: string;
event_type: number;
file_path: string;
msg_type: number;
name: string;
notification_style: number;
pic_url: string;
push_count: number;
session_id: string;
storage_type: number;
t: number;
tfcard_status: number;
timeout: number;
unique_id: string;
}
export interface ServerPushData {
email: string;
nick_name: string;
verify_code: string;
}
export interface PushMessage {
name: string;
event_time: number;
type: number;
station_sn: string;
device_sn: string;
title?: string;
content?: string;
push_time?: number;
channel?: number;
cipher?: number;
event_session?: string;
event_type?: number;
file_path?: string;
pic_url?: string;
push_count?: number;
notification_style?: number;
tfcard_status?: number;
alarm_delay_type?: number;
alarm_delay?: number;
alarm_type?: number;
sound_alarm?: boolean;
user_name?: string;
user_type?: number;
user_id?: string;
short_user_id?: string;
station_guard_mode?: number;
station_current_mode?: number;
person_name?: string;
sensor_open?: boolean;
device_online?: boolean;
fetch_id?: number;
sense_id?: number;
battery_powered?: boolean;
battery_low?: number;
storage_type?: number;
unique_id?: string;
automation_id?: number;
click_action?: string;
news_id?: number;
doorbell_url?: string;
doorbell_url_ex?: string;
doorbell_video_url?: string;
msg_type?: number;
timeout?: number;
event_value?: number | SmartSafeEventValueDetail;
person_id?: number;
door_id?: number;
power?: number;
email?: string;
verify_code?: string;
alarm_status?: string;
alarm_action?: AlarmAction;
open?: number;
openType?: number;
pin?: string;
}
export interface PlatformPushMode {
a: number;
alarm: number;
arming: number;
channel: number;
cipher: number;
create_time: number;
device_sn: string;
event_type: number;
face_id: number;
file_path: string;
mode: number;
msg_type: number;
name: string;
nick_name: string;
notification_style: number;
parted_status: number;
pic_url: string;
push_count: number;
record_id: number;
s: string;
session_id: string;
storage_type: number;
t: number;
tfcard_status: number;
timeout: number;
unique_id: string;
user: number;
user_name: string;
pic_filepath: string;
trigger_time: number;
alarm_delay: number;
person_id: number;
}
export interface AlarmPushData {
alarm_action_channel: AlarmAction;
alarm_id: string;
alarm_status: string;
alert_time: number;
device_sn: string;
station_sn: string;
}

38
build/push/models.js Normal file
View File

@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageTag = exports.ProcessingState = void 0;
var ProcessingState;
(function (ProcessingState) {
// Processing the version, tag, and size packets (assuming minimum length
// size packet). Only used during the login handshake.
ProcessingState[ProcessingState["MCS_VERSION_TAG_AND_SIZE"] = 0] = "MCS_VERSION_TAG_AND_SIZE";
// Processing the tag and size packets (assuming minimum length size
// packet). Used for normal messages.
ProcessingState[ProcessingState["MCS_TAG_AND_SIZE"] = 1] = "MCS_TAG_AND_SIZE";
// Processing the size packet alone.
ProcessingState[ProcessingState["MCS_SIZE"] = 2] = "MCS_SIZE";
// Processing the protocol buffer bytes (for those messages with non-zero
// sizes).
ProcessingState[ProcessingState["MCS_PROTO_BYTES"] = 3] = "MCS_PROTO_BYTES";
})(ProcessingState || (exports.ProcessingState = ProcessingState = {}));
var MessageTag;
(function (MessageTag) {
MessageTag[MessageTag["HeartbeatPing"] = 0] = "HeartbeatPing";
MessageTag[MessageTag["HeartbeatAck"] = 1] = "HeartbeatAck";
MessageTag[MessageTag["LoginRequest"] = 2] = "LoginRequest";
MessageTag[MessageTag["LoginResponse"] = 3] = "LoginResponse";
MessageTag[MessageTag["Close"] = 4] = "Close";
MessageTag[MessageTag["MessageStanza"] = 5] = "MessageStanza";
MessageTag[MessageTag["PresenceStanza"] = 6] = "PresenceStanza";
MessageTag[MessageTag["IqStanza"] = 7] = "IqStanza";
MessageTag[MessageTag["DataMessageStanza"] = 8] = "DataMessageStanza";
MessageTag[MessageTag["BatchPresenceStanza"] = 9] = "BatchPresenceStanza";
MessageTag[MessageTag["StreamErrorStanza"] = 10] = "StreamErrorStanza";
MessageTag[MessageTag["HttpRequest"] = 11] = "HttpRequest";
MessageTag[MessageTag["HttpResponse"] = 12] = "HttpResponse";
MessageTag[MessageTag["BindAccountRequest"] = 13] = "BindAccountRequest";
MessageTag[MessageTag["BindAccountResponse"] = 14] = "BindAccountResponse";
MessageTag[MessageTag["TalkMetadata"] = 15] = "TalkMetadata";
MessageTag[MessageTag["NumProtoTypes"] = 16] = "NumProtoTypes";
})(MessageTag || (exports.MessageTag = MessageTag = {}));
//# sourceMappingURL=models.js.map

1
build/push/models.js.map Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/push/models.ts"],"names":[],"mappings":";;;AAsKA,IAAY,eAYX;AAZD,WAAY,eAAe;IACvB,yEAAyE;IACzE,sDAAsD;IACtD,6FAA4B,CAAA;IAC5B,oEAAoE;IACpE,qCAAqC;IACrC,6EAAoB,CAAA;IACpB,oCAAoC;IACpC,6DAAY,CAAA;IACZ,yEAAyE;IACzE,UAAU;IACV,2EAAmB,CAAA;AACvB,CAAC,EAZW,eAAe,+BAAf,eAAe,QAY1B;AAED,IAAY,UAkBX;AAlBD,WAAY,UAAU;IAClB,6DAAiB,CAAA;IACjB,2DAAgB,CAAA;IAChB,2DAAgB,CAAA;IAChB,6DAAiB,CAAA;IACjB,6CAAS,CAAA;IACT,6DAAiB,CAAA;IACjB,+DAAkB,CAAA;IAClB,mDAAY,CAAA;IACZ,qEAAqB,CAAA;IACrB,yEAAuB,CAAA;IACvB,sEAAsB,CAAA;IACtB,0DAAgB,CAAA;IAChB,4DAAiB,CAAA;IACjB,wEAAuB,CAAA;IACvB,0EAAwB,CAAA;IACxB,4DAAiB,CAAA;IACjB,8DAAkB,CAAA;AACtB,CAAC,EAlBW,UAAU,0BAAV,UAAU,QAkBrB"}

25
build/push/parser.d.ts vendored Normal file
View File

@ -0,0 +1,25 @@
import { TypedEmitter } from "tiny-typed-emitter";
import { PushClientParserEvents } from "./interfaces";
export declare class PushClientParser extends TypedEmitter<PushClientParserEvents> {
private static proto;
private state;
private data;
private isWaitingForData;
private sizePacketSoFar;
private messageSize;
private messageTag;
private handshakeComplete;
private constructor();
resetState(): void;
static init(): Promise<PushClientParser>;
handleData(newData: Buffer): void;
private waitForData;
private handleFullMessage;
private onGotVersion;
private onGotMessageTag;
private onGotMessageSize;
private onGotMessageBytes;
private getNextMessage;
private getMinBytesNeeded;
private buildProtobufFromTag;
}

217
build/push/parser.js Normal file
View File

@ -0,0 +1,217 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PushClientParser = void 0;
const path = __importStar(require("path"));
const protobufjs_1 = require("protobufjs");
const tiny_typed_emitter_1 = require("tiny-typed-emitter");
const models_1 = require("./models");
const error_1 = require("../error");
const error_2 = require("./error");
const logging_1 = require("../logging");
class PushClientParser extends tiny_typed_emitter_1.TypedEmitter {
static proto = null;
state = models_1.ProcessingState.MCS_VERSION_TAG_AND_SIZE;
data = Buffer.alloc(0);
isWaitingForData = true;
sizePacketSoFar = 0;
messageSize = 0;
messageTag = 0;
handshakeComplete = false;
constructor() {
super();
}
resetState() {
this.state = models_1.ProcessingState.MCS_VERSION_TAG_AND_SIZE;
this.data = Buffer.alloc(0);
this.isWaitingForData = true;
this.sizePacketSoFar = 0;
this.messageSize = 0;
this.messageTag = 0;
this.handshakeComplete = false;
this.removeAllListeners();
}
static async init() {
this.proto = await (0, protobufjs_1.load)(path.join(__dirname, "./proto/mcs.proto"));
return new PushClientParser();
}
handleData(newData) {
this.data = Buffer.concat([this.data, newData]);
if (this.isWaitingForData) {
this.isWaitingForData = false;
this.waitForData();
}
}
waitForData() {
const minBytesNeeded = this.getMinBytesNeeded();
// If we don't have all bytes yet, wait some more
if (this.data.length < minBytesNeeded) {
this.isWaitingForData = true;
return;
}
else {
this.handleFullMessage();
}
}
handleFullMessage() {
switch (this.state) {
case models_1.ProcessingState.MCS_VERSION_TAG_AND_SIZE:
this.onGotVersion();
break;
case models_1.ProcessingState.MCS_TAG_AND_SIZE:
this.onGotMessageTag();
break;
case models_1.ProcessingState.MCS_SIZE:
this.onGotMessageSize();
break;
case models_1.ProcessingState.MCS_PROTO_BYTES:
this.onGotMessageBytes();
break;
default:
logging_1.rootPushLogger.warn("Push Parser - Unknown state", { state: this.state });
break;
}
}
onGotVersion() {
const version = this.data.readInt8(0);
this.data = this.data.subarray(1);
if (version < 41 && version !== 38) {
throw new error_2.MCSProtocolVersionError("Got wrong protocol version", { context: { version: version } });
}
// Process the LoginResponse message tag.
this.onGotMessageTag();
}
onGotMessageTag() {
this.messageTag = this.data.readInt8(0);
this.data = this.data.subarray(1);
this.onGotMessageSize();
}
onGotMessageSize() {
let incompleteSizePacket = false;
const reader = new protobufjs_1.BufferReader(this.data);
try {
this.messageSize = reader.int32();
}
catch (err) {
const error = (0, error_1.ensureError)(err);
if (error instanceof Error && error.message.startsWith("index out of range:")) {
incompleteSizePacket = true;
}
else {
throw error;
}
}
if (incompleteSizePacket) {
this.sizePacketSoFar = reader.pos;
this.state = models_1.ProcessingState.MCS_SIZE;
this.waitForData();
return;
}
this.data = this.data.subarray(reader.pos);
this.sizePacketSoFar = 0;
if (this.messageSize > 0) {
this.state = models_1.ProcessingState.MCS_PROTO_BYTES;
this.waitForData();
}
else {
this.onGotMessageBytes();
}
}
onGotMessageBytes() {
const protobuf = this.buildProtobufFromTag(this.messageTag);
if (this.messageSize === 0) {
this.emit("message", { tag: this.messageTag, object: {} });
this.getNextMessage();
return;
}
if (this.data.length < this.messageSize) {
this.state = models_1.ProcessingState.MCS_PROTO_BYTES;
this.waitForData();
return;
}
const buffer = this.data.subarray(0, this.messageSize);
this.data = this.data.subarray(this.messageSize);
const message = protobuf.decode(buffer);
const object = protobuf.toObject(message, {
longs: String,
enums: String,
bytes: Buffer,
});
this.emit("message", { tag: this.messageTag, object: object });
if (this.messageTag === models_1.MessageTag.LoginResponse) {
if (this.handshakeComplete) {
logging_1.rootPushLogger.error("Push Parser - Unexpected login response!");
}
else {
this.handshakeComplete = true;
}
}
this.getNextMessage();
}
getNextMessage() {
this.messageTag = 0;
this.messageSize = 0;
this.state = models_1.ProcessingState.MCS_TAG_AND_SIZE;
this.waitForData();
}
getMinBytesNeeded() {
switch (this.state) {
case models_1.ProcessingState.MCS_VERSION_TAG_AND_SIZE:
return 1 + 1 + 1;
case models_1.ProcessingState.MCS_TAG_AND_SIZE:
return 1 + 1;
case models_1.ProcessingState.MCS_SIZE:
return this.sizePacketSoFar + 1;
case models_1.ProcessingState.MCS_PROTO_BYTES:
return this.messageSize;
default:
throw new error_2.MCSProtocolProcessingStateError("Unknown protocol processing state", { context: { state: this.state } });
}
}
buildProtobufFromTag(messageTag) {
switch (messageTag) {
case models_1.MessageTag.HeartbeatPing:
return PushClientParser.proto.lookupType("mcs_proto.HeartbeatPing");
case models_1.MessageTag.HeartbeatAck:
return PushClientParser.proto.lookupType("mcs_proto.HeartbeatAck");
case models_1.MessageTag.LoginRequest:
return PushClientParser.proto.lookupType("mcs_proto.LoginRequest");
case models_1.MessageTag.LoginResponse:
return PushClientParser.proto.lookupType("mcs_proto.LoginResponse");
case models_1.MessageTag.Close:
return PushClientParser.proto.lookupType("mcs_proto.Close");
case models_1.MessageTag.IqStanza:
return PushClientParser.proto.lookupType("mcs_proto.IqStanza");
case models_1.MessageTag.DataMessageStanza:
return PushClientParser.proto.lookupType("mcs_proto.DataMessageStanza");
case models_1.MessageTag.StreamErrorStanza:
return PushClientParser.proto.lookupType("mcs_proto.StreamErrorStanza");
default:
throw new error_2.MCSProtocolMessageTagError("Unknown protocol message tag", { context: { messageTag: this.messageTag } });
}
}
}
exports.PushClientParser = PushClientParser;
//# sourceMappingURL=parser.js.map

1
build/push/parser.js.map Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,266 @@
// Sample data, if provided, is fished from a Nexus 7 (2013) / flo running Android 5.0
message CheckinRequest {
// unused
optional string imei = 1;
// Gservices["android_id"] or 0 on first-checkin
optional int64 androidId = 2;
// Gservices["digest"] or ""
optional string digest = 3;
required Checkin checkin = 4;
message Checkin {
// empty Build on pre-checkin
required Build build = 1;
message Build {
// Build.FINGERPRINT
// eg. google/razor/flo:5.0.1/LRX22C/1602158:user/release-keys
optional string fingerprint = 1;
// Build.HARDWARE
// eg. flo
optional string hardware = 2;
// Build.BRAND
// eg. google
optional string brand = 3;
// Build.getRadioVersion()
optional string radio = 4;
// Build.BOOTLOADER
// eg. FLO-04.04
optional string bootloader = 5;
// GoogleSettingsContract.Partner["client_id"]
// eg. android-google
optional string clientId = 6;
// Build.TIME / 1000L
// eg. 1416533192
optional int64 time = 7;
// PackageInfo.versionCode
// eg. 6188736
optional int32 packageVersionCode = 8;
// Build.DEVICE
// eg. flo
optional string device = 9;
// Build.VERSION.SDK_INT
// eg. 21
optional int32 sdkVersion = 10;
// Build.MODEL
// eg. Nexus 7
optional string model = 11;
// Build.MANUFACTURER
// eg. asus
optional string manufacturer = 12;
// Build.PRODUCT
// eg. razor
optional string product = 13;
// fileExists("/system/recovery-from-boot.p")
// eg. false
optional bool otaInstalled = 14;
}
// last checkin ms or 0 if first checkin
// eg. 0
optional int64 lastCheckinMs = 2;
// eg. ("event_log_start",~,1424612602652) on first checkin
repeated Event event = 3;
message Event {
optional string tag = 1;
optional string value = 2;
optional int64 timeMs = 3;
}
// unknown, n/a on first checkin
repeated Statistic stat = 4;
message Statistic {
required string tag = 1;
optional int32 count = 2;
optional float sum = 3;
}
// unused
repeated string requestedGroup = 5;
// TelephonyManager.getNetworkOperator != null|empty
optional string cellOperator = 6;
// TelephonyManager.getSimOperator != null|empty
optional string simOperator = 7;
// "WIFI::" | ("mobile" | "notmobile" | "unknown") + "-" + ("roaming" | "notroaming" | "unknown")
optional string roaming = 8;
// UserHandle.myUserId
// eg. 0
optional int32 userNumber = 9;
}
// unused
optional string desiredBuild = 5;
// Locale.toString
optional string locale = 6;
// GoogleSettingsContract.Partner["logging_id2"] (choosen randomly on first checkin)
// eg. 12561488293572742346
optional int64 loggingId = 7;
// unused
optional string marketCheckin = 8;
// NetworkInfo.getExtraInfo, WifiInfo.getMacAddress (12 hex-digits)
// eg. d850e6abcdef
repeated string macAddress = 9;
// TelephonyManager.getDeviceId (14 hex-digits), not set on tablets
optional string meid = 10;
// "[<email>]" followed by "<authToken>", empty string on first checkin
repeated string accountCookie = 11;
// TimeZone.getId
// eg. GMT
optional string timeZone = 12;
// security token as given on first checkin, not set on first checkin
optional fixed64 securityToken = 13;
// use 3
optional int32 version = 14;
// SHA-1 of each in /system/etc/security/otacerts.zip or "--IOException--" or "--no-output--"
// eg. dKXTm1QH9QShGQwBM/4rg6/lCNQ=
repeated string otaCert = 15;
// Build.SERIAL != "unknown"
// eg. 07d90b18
optional string serial = 16;
// TelephonyManager.getDeviceId (8 hex-digits), not set on tablets
optional string esn = 17;
optional DeviceConfig deviceConfiguration = 18;
message DeviceConfig {
// ConfigurationInfo.reqTouchScreen
// eg. 3
optional int32 touchScreen = 1;
// ConfigurationInfo.reqKeyboardType
// eg. 1
optional int32 keyboardType = 2;
// ConfigurationInfo.reqNavigation
// eg. 1
optional int32 navigation = 3;
// ConfigurationInfo.screenLayout
// eg. 3
optional int32 screenLayout = 4;
// ConfigurationInfo.reqInputFeatures & ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD
// eg. 0
optional bool hasHardKeyboard = 5;
// ConfigurationInfo.reqInputFeatures & ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV
// eg. 0
optional bool hasFiveWayNavigation = 6;
// DisplayMetrics.densityDpi
// eg. 320
optional int32 densityDpi = 7;
// ConfigurationInfo.reqGlEsVersion
// eg. 196608
optional int32 glEsVersion = 8;
// PackageManager.getSystemSharedLibraryNames
// eg. "android.test.runner", "com.android.future.usb.accessory", "com.android.location.provider",
// "com.android.media.remotedisplay", "com.android.mediadrm.signer", "com.google.android.maps",
// "com.google.android.media.effects", "com.google.widevine.software.drm", "javax.obex"
repeated string sharedLibrary = 9;
// PackageManager.getSystemAvailableFeatures
// eg. android.hardware.[...]
repeated string availableFeature = 10;
// Build.CPU_ABI and Build.CPU_ABI2 != "unknown"
// eg. "armeabi-v7a", "armeabi"
repeated string nativePlatform = 11;
// DisplayMetrics.widthPixels
// eg. 1200
optional int32 widthPixels = 12;
// DisplayMetrics.heightPixels
// eg. 1824
optional int32 heightPixels = 13;
// Context.getAssets.getLocales
// eg. [...], "en-US", [...]
repeated string locale = 14;
// GLES10.glGetString(GLES10.GL_EXTENSIONS)
// eg. "GL_AMD_compressed_ATC_texture", [...]
repeated string glExtension = 15;
// unused
optional int32 deviceClass = 16;
// unused
optional int32 maxApkDownloadSizeMb = 17;
}
// "ethernet" or "wifi"
repeated string macAddressType = 19;
// unknown, use 0 on pre- and first-checkin, and 1 for later checkins
// also present on pre-checkin
required int32 fragment = 20;
// unknown
optional string userName = 21;
// UserManager.getUserSerialNumber
// eg. 0
optional int32 userSerialNumber = 22;
}
message CheckinResponse {
optional bool statsOk = 1;
repeated Intent intent = 2;
message Intent {
optional string action = 1;
optional string dataUri = 2;
optional string mimeType = 3;
optional string javaClass = 4;
repeated Extra extra = 5;
message Extra {
optional string name = 6;
optional string value = 7;
}
}
optional int64 timeMs = 3;
optional string digest = 4;
repeated GservicesSetting setting = 5;
message GservicesSetting {
optional bytes name = 1;
optional bytes value = 2;
}
optional bool marketOk = 6;
optional fixed64 androidId = 7;
optional fixed64 securityToken = 8;
optional bool settingsDiff = 9;
repeated string deleteSetting = 10;
optional string versionInfo = 11;
optional string deviceDataVersionInfo = 12;
}

328
build/push/proto/mcs.proto Normal file
View File

@ -0,0 +1,328 @@
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// MCS protocol for communication between Chrome client and Mobile Connection
// Server .
syntax = "proto2";
option optimize_for = LITE_RUNTIME;
package mcs_proto;
/*
Common fields/comments:
stream_id: no longer sent by server, each side keeps a counter
last_stream_id_received: sent only if a packet was received since last time
a last_stream was sent
status: new bitmask including the 'idle' as bit 0.
*/
/**
TAG: 0
*/
message HeartbeatPing {
optional int32 stream_id = 1;
optional int32 last_stream_id_received = 2;
optional int64 status = 3;
}
/**
TAG: 1
*/
message HeartbeatAck {
optional int32 stream_id = 1;
optional int32 last_stream_id_received = 2;
optional int64 status = 3;
}
message ErrorInfo {
required int32 code = 1;
optional string message = 2;
optional string type = 3;
optional Extension extension = 4;
}
// MobileSettings class.
// "u:f", "u:b", "u:s" - multi user devices reporting foreground, background
// and stopped users.
// hbping: heatbeat ping interval
// rmq2v: include explicit stream IDs
message Setting {
required string name = 1;
required string value = 2;
}
message HeartbeatStat {
required string ip = 1;
required bool timeout = 2;
required int32 interval_ms = 3;
}
message HeartbeatConfig {
optional bool upload_stat = 1;
optional string ip = 2;
optional int32 interval_ms = 3;
}
// ClientEvents are used to inform the server of failed and successful
// connections.
message ClientEvent {
enum Type {
UNKNOWN = 0;
// Count of discarded events if the buffer filled up and was trimmed.
DISCARDED_EVENTS = 1;
// Failed connection event: the connection failed to be established or we
// had a login error.
FAILED_CONNECTION = 2;
// Successful connection event: information about the last successful
// connection, including the time at which it was established.
SUCCESSFUL_CONNECTION = 3;
}
// Common fields [1-99]
optional Type type = 1;
// Fields for DISCARDED_EVENTS messages [100-199]
optional uint32 number_discarded_events = 100;
// Fields for FAILED_CONNECTION and SUCCESSFUL_CONNECTION messages [200-299]
// Network type is a value in net::NetworkChangeNotifier::ConnectionType.
optional int32 network_type = 200;
// Reserved for network_port.
reserved 201;
optional uint64 time_connection_started_ms = 202;
optional uint64 time_connection_ended_ms = 203;
// Error code should be a net::Error value.
optional int32 error_code = 204;
// Fields for SUCCESSFUL_CONNECTION messages [300-399]
optional uint64 time_connection_established_ms = 300;
}
/**
TAG: 2
*/
message LoginRequest {
enum AuthService {
ANDROID_ID = 2;
}
required string id = 1; // Must be present ( proto required ), may be empty
// string.
// mcs.android.com.
required string domain = 2;
// Decimal android ID
required string user = 3;
required string resource = 4;
// Secret
required string auth_token = 5;
// Format is: android-HEX_DEVICE_ID
// The user is the decimal value.
optional string device_id = 6;
// RMQ1 - no longer used
optional int64 last_rmq_id = 7;
repeated Setting setting = 8;
//optional int32 compress = 9;
repeated string received_persistent_id = 10;
// Replaced by "rmq2v" setting
// optional bool include_stream_ids = 11;
optional bool adaptive_heartbeat = 12;
optional HeartbeatStat heartbeat_stat = 13;
// Must be true.
optional bool use_rmq2 = 14;
optional int64 account_id = 15;
// ANDROID_ID = 2
optional AuthService auth_service = 16;
optional int32 network_type = 17;
optional int64 status = 18;
// 19, 20, and 21 are not currently populated by Chrome.
reserved 19, 20, 21;
// Events recorded on the client after the last successful connection.
repeated ClientEvent client_event = 22;
}
/**
* TAG: 3
*/
message LoginResponse {
required string id = 1;
// Not used.
optional string jid = 2;
// Null if login was ok.
optional ErrorInfo error = 3;
repeated Setting setting = 4;
optional int32 stream_id = 5;
// Should be "1"
optional int32 last_stream_id_received = 6;
optional HeartbeatConfig heartbeat_config = 7;
// used by the client to synchronize with the server timestamp.
optional int64 server_timestamp = 8;
}
message StreamErrorStanza {
required string type = 1;
optional string text = 2;
}
/**
* TAG: 4
*/
message Close {
}
message Extension {
// 12: SelectiveAck
// 13: StreamAck
required int32 id = 1;
required bytes data = 2;
}
/**
* TAG: 7
* IqRequest must contain a single extension. IqResponse may contain 0 or 1
* extensions.
*/
message IqStanza {
enum IqType {
GET = 0;
SET = 1;
RESULT = 2;
IQ_ERROR = 3;
}
optional int64 rmq_id = 1;
required IqType type = 2;
required string id = 3;
optional string from = 4;
optional string to = 5;
optional ErrorInfo error = 6;
// Only field used in the 38+ protocol (besides common last_stream_id_received, status, rmq_id)
optional Extension extension = 7;
optional string persistent_id = 8;
optional int32 stream_id = 9;
optional int32 last_stream_id_received = 10;
optional int64 account_id = 11;
optional int64 status = 12;
}
message AppData {
required string key = 1;
required string value = 2;
}
/**
* TAG: 8
*/
message DataMessageStanza {
// Not used.
// optional int64 rmq_id = 1;
// This is the message ID, set by client, DMP.9 (message_id)
optional string id = 2;
// Project ID of the sender, DMP.1
required string from = 3;
// Part of DMRequest - also the key in DataMessageProto.
optional string to = 4;
// Package name. DMP.2
required string category = 5;
// The collapsed key, DMP.3
optional string token = 6;
// User data + GOOGLE. prefixed special entries, DMP.4
repeated AppData app_data = 7;
// Not used.
optional bool from_trusted_server = 8;
// Part of the ACK protocol, returned in DataMessageResponse on server side.
// It's part of the key of DMP.
optional string persistent_id = 9;
// In-stream ack. Increments on each message sent - a bit redundant
// Not used in DMP/DMR.
optional int32 stream_id = 10;
optional int32 last_stream_id_received = 11;
// Not used.
// optional string permission = 12;
// Sent by the device shortly after registration.
optional string reg_id = 13;
// Not used.
// optional string pkg_signature = 14;
// Not used.
// optional string client_id = 15;
// serial number of the target user, DMP.8
// It is the 'serial number' according to user manager.
optional int64 device_user_id = 16;
// Time to live, in seconds.
optional int32 ttl = 17;
// Timestamp ( according to client ) when message was sent by app, in seconds
optional int64 sent = 18;
// How long has the message been queued before the flush, in seconds.
// This is needed to account for the time difference between server and
// client: server should adjust 'sent' based on its 'receive' time.
optional int32 queued = 19;
optional int64 status = 20;
// Optional field containing the binary payload of the message.
optional bytes raw_data = 21;
// Not used.
// The maximum delay of the message, in seconds.
// optional int32 max_delay = 22;
// Not used.
// How long the message was delayed before it was sent, in seconds.
// optional int32 actual_delay = 23;
// If set the server requests immediate ack. Used for important messages and
// for testing.
optional bool immediate_ack = 24;
// Not used.
// Enables message receipts from MCS/GCM back to CCS clients
// optional bool delivery_receipt_requested = 25;
}
/**
Included in IQ with ID 13, sent from client or server after 10 unconfirmed
messages.
*/
message StreamAck {
// No last_streamid_received required. This is included within an IqStanza,
// which includes the last_stream_id_received.
}
/**
Included in IQ sent after LoginResponse from server with ID 12.
*/
message SelectiveAck {
repeated string id = 1;
}

46
build/push/service.d.ts vendored Normal file
View File

@ -0,0 +1,46 @@
import { TypedEmitter } from "tiny-typed-emitter";
import { Credentials } from "./models";
import { PushNotificationServiceEvents } from "./interfaces";
export declare class PushNotificationService extends TypedEmitter<PushNotificationServiceEvents> {
private readonly APP_PACKAGE;
private readonly APP_ID;
private readonly APP_SENDER_ID;
private readonly APP_CERT_SHA1;
private readonly FCM_PROJECT_ID;
private readonly GOOGLE_API_KEY;
private readonly AUTH_VERSION;
private pushClient?;
private credentialsTimeout?;
private retryTimeout?;
private retryDelay;
private credentials;
private persistentIds;
private connected;
private connecting;
private got;
private constructor();
private loadLibraries;
static initialize(): Promise<PushNotificationService>;
private buildExpiresAt;
private registerFid;
private renewFidToken;
private createPushCredentials;
private renewPushCredentials;
private loginPushCredentials;
private executeCheckin;
private registerGcm;
private _normalizePushMessage;
private onMessage;
private getCurrentPushRetryDelay;
setCredentials(credentials: Credentials): void;
getCredentials(): Credentials | undefined;
setPersistentIds(persistentIds: string[]): void;
getPersistentIds(): string[];
private _open;
open(): Promise<Credentials | undefined>;
close(): void;
private clearCredentialsTimeout;
private clearRetryTimeout;
private resetRetryTimeout;
isConnected(): boolean;
}

818
build/push/service.js Normal file
View File

@ -0,0 +1,818 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PushNotificationService = void 0;
const qs = __importStar(require("qs"));
const tiny_typed_emitter_1 = require("tiny-typed-emitter");
const utils_1 = require("./utils");
const client_1 = require("./client");
const device_1 = require("../http/device");
const types_1 = require("../http/types");
const utils_2 = require("../http/utils");
const utils_3 = require("../utils");
const error_1 = require("./error");
const error_2 = require("../error");
const logging_1 = require("../logging");
const _1 = require(".");
const station_1 = require("../http/station");
class PushNotificationService extends tiny_typed_emitter_1.TypedEmitter {
APP_PACKAGE = "com.oceanwing.battery.cam";
APP_ID = "1:348804314802:android:440a6773b3620da7";
APP_SENDER_ID = "348804314802";
APP_CERT_SHA1 = "F051262F9F99B638F3C76DE349830638555B4A0A";
FCM_PROJECT_ID = "batterycam-3250a";
GOOGLE_API_KEY = "AIzaSyCSz1uxGrHXsEktm7O3_wv-uLGpC9BvXR8";
AUTH_VERSION = "FIS_v2";
pushClient;
credentialsTimeout;
retryTimeout;
retryDelay = 0;
credentials;
persistentIds = [];
connected = false;
connecting = false;
got;
constructor() {
super();
}
async loadLibraries() {
const { default: got } = await import("got");
this.got = got;
}
static async initialize() {
const service = new PushNotificationService();
await service.loadLibraries();
return service;
}
buildExpiresAt(expiresIn) {
if (expiresIn.endsWith("ms")) {
return new Date().getTime() + Number.parseInt(expiresIn.substring(0, expiresIn.length - 2));
}
else if (expiresIn.endsWith("s")) {
return new Date().getTime() + Number.parseInt(expiresIn.substring(0, expiresIn.length - 1)) * 1000;
}
throw new error_1.UnknownExpiryFormaError("Unknown expiresIn-format", { context: { format: expiresIn } });
}
async registerFid(fid) {
const url = `https://firebaseinstallations.googleapis.com/v1/projects/${this.FCM_PROJECT_ID}/installations`;
try {
const response = await this.got(url, {
method: "post",
json: {
fid: fid,
appId: `${this.APP_ID}`,
authVersion: `${this.AUTH_VERSION}`,
sdkVersion: "a:16.3.1",
},
headers: {
"X-Android-Package": `${this.APP_PACKAGE}`,
"X-Android-Cert": `${this.APP_CERT_SHA1}`,
"x-goog-api-key": `${this.GOOGLE_API_KEY}`,
},
responseType: "json",
http2: false,
throwHttpErrors: false,
retry: {
limit: 3,
methods: ["POST"]
},
hooks: {
beforeError: [
error => {
const { response, options } = error;
const statusCode = response?.statusCode || 0;
const { method, url, prefixUrl } = options;
const shortUrl = (0, utils_3.getShortUrl)(typeof url === "string" ? new URL(url) : url === undefined ? new URL("") : url, typeof prefixUrl === "string" ? prefixUrl : prefixUrl.toString());
const body = response?.body ? response.body : error.message;
if (response?.body) {
error.name = "RegisterFidError";
error.message = `${statusCode} ${method} ${shortUrl}\n${body}`;
}
return error;
}
]
}
});
if (response.statusCode == 200) {
const result = response.body;
return {
...result,
authToken: {
...result.authToken,
expiresAt: this.buildExpiresAt(result.authToken.expiresIn),
},
};
}
else {
logging_1.rootPushLogger.error("Register FID - Status return code not 200", { status: response.statusCode, statusText: response.statusMessage, data: response.body });
throw new error_1.FidRegistrationFailedError("FID registration failed", { context: { status: response.statusCode, statusText: response.statusMessage, data: response.body } });
}
}
catch (err) {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error("Register FID - Generic Error", { error: (0, utils_3.getError)(error) });
throw new error_1.FidRegistrationFailedError("FID registration failed", { cause: error, context: { fid: fid } });
}
}
async renewFidToken(fid, refreshToken) {
const url = `https://firebaseinstallations.googleapis.com/v1/projects/${this.FCM_PROJECT_ID}/installations/${fid}/authTokens:generate`;
try {
const response = await this.got(url, {
method: "post",
json: {
installation: {
appId: `${this.APP_ID}`,
sdkVersion: "a:16.3.1",
}
},
headers: {
"X-Android-Package": `${this.APP_PACKAGE}`,
"X-Android-Cert": `${this.APP_CERT_SHA1}`,
"x-goog-api-key": `${this.GOOGLE_API_KEY}`,
Authorization: `${this.AUTH_VERSION} ${refreshToken}`
},
responseType: "json",
http2: false,
throwHttpErrors: false,
retry: {
limit: 3,
methods: ["POST"]
},
hooks: {
beforeError: [
error => {
const { response, options } = error;
const statusCode = response?.statusCode || 0;
const { method, url, prefixUrl } = options;
const shortUrl = (0, utils_3.getShortUrl)(typeof url === "string" ? new URL(url) : url === undefined ? new URL("") : url, typeof prefixUrl === "string" ? prefixUrl : prefixUrl.toString());
const body = response?.body ? response.body : error.message;
if (response?.body) {
error.name = "RenewFidTokenError";
error.message = `${statusCode} ${method} ${shortUrl}\n${body}`;
}
return error;
}
]
}
});
if (response.statusCode == 200) {
const result = response.body;
return {
...result,
expiresAt: this.buildExpiresAt(result.expiresIn),
};
}
else {
logging_1.rootPushLogger.error("Renew FID Token - Status return code not 200", { status: response.statusCode, statusText: response.statusMessage, data: response.body });
throw new error_1.RenewFidTokenFailedError("FID Token renewal failed", { context: { status: response.statusCode, statusText: response.statusMessage, data: response.body } });
}
}
catch (err) {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error("Renew FID Token - Generic Error", { error: (0, utils_3.getError)(error) });
throw new error_1.RenewFidTokenFailedError("FID Token renewal failed", { cause: error, context: { fid: fid, refreshToken: refreshToken } });
}
}
async createPushCredentials() {
const generatedFid = (0, utils_1.generateFid)();
return await this.registerFid(generatedFid)
.then(async (registerFidResponse) => {
const checkinResponse = await this.executeCheckin();
return {
fidResponse: registerFidResponse,
checkinResponse: checkinResponse
};
})
.then(async (result) => {
const registerGcmResponse = await this.registerGcm(result.fidResponse, result.checkinResponse);
return {
...result,
gcmResponse: registerGcmResponse,
};
}).catch((err) => {
const error = (0, error_2.ensureError)(err);
throw error;
});
}
async renewPushCredentials(credentials) {
return await this.renewFidToken(credentials.fidResponse.fid, credentials.fidResponse.refreshToken)
.then(async (response) => {
credentials.fidResponse.authToken = response;
return await this.executeCheckin();
})
.then(async (response) => {
const registerGcmResponse = await this.registerGcm(credentials.fidResponse, response);
return {
fidResponse: credentials.fidResponse,
checkinResponse: response,
gcmResponse: registerGcmResponse,
};
})
.catch(() => {
return this.createPushCredentials();
});
}
async loginPushCredentials(credentials) {
logging_1.rootPushLogger.info('fidresponse', credentials.fidResponse);
return await this.executeCheckin()
.then(async (response) => {
const registerGcmResponse = await this.registerGcm(credentials.fidResponse, response);
return {
fidResponse: credentials.fidResponse,
checkinResponse: response,
gcmResponse: registerGcmResponse,
};
})
.catch(() => {
return this.createPushCredentials();
});
}
async executeCheckin() {
const url = "https://android.clients.google.com/checkin";
try {
const buffer = await (0, utils_1.buildCheckinRequest)();
const response = await this.got(url, {
method: "post",
body: Buffer.from(buffer),
headers: {
"Content-Type": "application/x-protobuf",
},
responseType: "buffer",
http2: false,
throwHttpErrors: false,
retry: {
limit: 3,
methods: ["POST"]
},
hooks: {
beforeError: [
error => {
const { response, options } = error;
const statusCode = response?.statusCode || 0;
const { method, url, prefixUrl } = options;
const shortUrl = (0, utils_3.getShortUrl)(typeof url === "string" ? new URL(url) : url === undefined ? new URL("") : url, typeof prefixUrl === "string" ? prefixUrl : prefixUrl.toString());
const body = response?.body ? response.body : error.message;
if (response?.body) {
error.name = "ExecuteCheckInError";
error.message = `${statusCode} ${method} ${shortUrl}\n${body}`;
}
return error;
}
]
}
});
if (response.statusCode == 200) {
return await (0, utils_1.parseCheckinResponse)(response.body);
}
else {
logging_1.rootPushLogger.error("Check in - Status return code not 200", { status: response.statusCode, statusText: response.statusMessage, data: response.body });
throw new error_1.ExecuteCheckInError("Google checkin failed", { context: { status: response.statusCode, statusText: response.statusMessage, data: response.body } });
}
}
catch (err) {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error("Check in - Generic Error", { error: (0, utils_3.getError)(error) });
throw new error_1.ExecuteCheckInError("Google checkin failed", { cause: error });
}
}
async registerGcm(fidInstallationResponse, checkinResponse) {
const url = "https://android.clients.google.com/c2dm/register3";
const androidId = checkinResponse.androidId;
const fid = fidInstallationResponse.fid;
const securityToken = checkinResponse.securityToken;
const retry = 5;
try {
for (let retry_count = 1; retry_count <= retry; retry_count++) {
logging_1.rootPushLogger.debug(`Register GCM - Attempt ${retry_count} of ${retry}`, { androidId: androidId, fid: fid, securityToken: securityToken });
const response = await this.got(url, {
method: "post",
body: qs.stringify({
"X-subtype": `${this.APP_SENDER_ID}`,
sender: `${this.APP_SENDER_ID}`,
"X-app_ver": "741",
"X-osv": "25",
"X-cliv": "fiid-20.2.0",
"X-gmsv": "201216023",
"X-appid": `${fid}`,
"X-scope": "*",
"X-Goog-Firebase-Installations-Auth": `${fidInstallationResponse.authToken.token}`,
"X-gmp_app_id": `${this.APP_ID}`,
"X-Firebase-Client": "fire-abt/17.1.1+fire-installations/16.3.1+fire-android/+fire-analytics/17.4.2+fire-iid/20.2.0+fire-rc/17.0.0+fire-fcm/20.2.0+fire-cls/17.0.0+fire-cls-ndk/17.0.0+fire-core/19.3.0",
"X-firebase-app-name-hash": "R1dAH9Ui7M-ynoznwBdw01tLxhI",
"X-Firebase-Client-Log-Type": "1",
"X-app_ver_name": "v2.2.2_741",
app: `${this.APP_PACKAGE}`,
device: `${androidId}`,
app_ver: "741",
info: "g3EMJXXElLwaQEb1aBJ6XhxiHjPTUxc",
gcm_ver: "201216023",
plat: "0",
cert: `${this.APP_CERT_SHA1}`,
target_ver: "28",
}),
headers: {
Authorization: `AidLogin ${androidId}:${securityToken}`,
app: `${this.APP_PACKAGE}`,
gcm_ver: "201216023",
"User-Agent": "Android-GCM/1.5",
"content-type": "application/x-www-form-urlencoded",
},
http2: false,
throwHttpErrors: false,
retry: {
limit: 3,
methods: ["POST"]
},
hooks: {
beforeError: [
error => {
const { response, options } = error;
const statusCode = response?.statusCode || 0;
const { method, url, prefixUrl } = options;
const shortUrl = (0, utils_3.getShortUrl)(typeof url === "string" ? new URL(url) : url === undefined ? new URL("") : url, typeof prefixUrl === "string" ? prefixUrl : prefixUrl.toString());
const body = response?.body ? response.body : error.message;
if (response?.body) {
error.name = "RegisterGcmError";
error.message = `${statusCode} ${method} ${shortUrl}\n${body}`;
}
return error;
}
]
}
});
if (response.statusCode == 200) {
const result = response.body.split("=");
if (result[0] == "Error") {
logging_1.rootPushLogger.debug("GCM register error, retry...", { retry: retry, retryCount: retry_count, response: response.body });
if (retry_count == retry)
throw new error_1.RegisterGcmError("Max GCM registration retries reached", { context: { message: result[1], retry: retry, retryCount: retry_count } });
}
else {
return {
token: result[1]
};
}
}
else {
logging_1.rootPushLogger.error("Register GCM - Status return code not 200", { status: response.statusCode, statusText: response.statusMessage, data: response.body });
throw new error_1.RegisterGcmError("Google register to GCM failed", { context: { status: response.statusCode, statusText: response.statusMessage, data: response.body } });
}
await (0, utils_1.sleep)(10000 * retry_count);
}
throw new error_1.RegisterGcmError("Max GCM registration retries reached");
}
catch (err) {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error("Register GCM - Generic Error", { error: (0, utils_3.getError)(error) });
throw new error_1.RegisterGcmError("Google register to GCM failed", { cause: error, context: { fidInstallationResponse: fidInstallationResponse, checkinResponse: checkinResponse } });
}
}
_normalizePushMessage(message) {
const normalizedMessage = {
name: "",
event_time: 0,
type: -1,
station_sn: "",
device_sn: ""
};
if (message.payload.payload) {
const payload = message.payload;
// CusPush
try {
normalizedMessage.type = Number.parseInt(payload.type);
}
catch (err) {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error(`Normalize push message - type - Error`, { error: (0, utils_3.getError)(error), message: message });
}
if (normalizedMessage.type in _1.ServerPushEvent) {
// server push notification
const serverPushData = payload.payload;
normalizedMessage.email = serverPushData.email;
normalizedMessage.person_name = serverPushData.nick_name;
normalizedMessage.verify_code = serverPushData.verify_code;
switch (normalizedMessage.type) {
case _1.ServerPushEvent.ALARM_NOTIFY:
case _1.ServerPushEvent.ALARM_GUEST_NOTIFY:
const alarmPushData = payload.payload;
normalizedMessage.device_sn = alarmPushData.device_sn;
normalizedMessage.station_sn = alarmPushData.station_sn;
normalizedMessage.alarm_status = alarmPushData.alarm_status;
normalizedMessage.alarm_action = alarmPushData.alarm_action_channel;
try {
normalizedMessage.alarm_type = Number.parseInt(alarmPushData.alarm_id);
}
catch (err) {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error(`Normalize push message - alarm_type - Error`, { error: (0, utils_3.getError)(error), message: message });
}
try {
normalizedMessage.event_time = alarmPushData.alert_time !== undefined ? (0, utils_1.convertTimestampMs)(alarmPushData.alert_time) : Number.parseInt(alarmPushData.alert_time);
}
catch (err) {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error(`Normalize push message - event_time - Error`, { error: (0, utils_3.getError)(error), message: message });
}
break;
}
}
else {
try {
normalizedMessage.event_time = payload.event_time !== undefined ? (0, utils_1.convertTimestampMs)(Number.parseInt(payload.event_time)) : Number.parseInt(payload.event_time);
}
catch (err) {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error(`Normalize push message - Type ${types_1.DeviceType[normalizedMessage.type]} CusPush - event_time - Error`, { error: (0, utils_3.getError)(error), message: message });
}
try {
normalizedMessage.push_time = payload.push_time !== undefined ? (0, utils_1.convertTimestampMs)(Number.parseInt(payload.push_time)) : Number.parseInt(payload.push_time);
}
catch (err) {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error(`Normalize push message - Type ${types_1.DeviceType[normalizedMessage.type]} CusPush - push_time - Error`, { error: (0, utils_3.getError)(error), message: message });
}
normalizedMessage.station_sn = payload.station_sn;
normalizedMessage.title = payload.title;
normalizedMessage.content = payload.content;
if (normalizedMessage.type === types_1.DeviceType.FLOODLIGHT)
normalizedMessage.device_sn = payload.station_sn;
else
normalizedMessage.device_sn = payload.device_sn;
if ((0, utils_3.isEmpty)(normalizedMessage.device_sn) && !(0, utils_3.isEmpty)(normalizedMessage.station_sn)) {
normalizedMessage.device_sn = normalizedMessage.station_sn;
}
if (station_1.Station.isStationHomeBase3(normalizedMessage.type) || (normalizedMessage.station_sn.startsWith("T8030") && (device_1.Device.isCamera(normalizedMessage.type)))) {
const platformPushData = payload.payload;
normalizedMessage.name = platformPushData.name ? platformPushData.name : "";
normalizedMessage.channel = platformPushData.channel !== undefined ? platformPushData.channel : 0;
normalizedMessage.cipher = platformPushData.cipher !== undefined ? platformPushData.cipher : 0;
normalizedMessage.event_session = platformPushData.session_id !== undefined ? platformPushData.session_id : "";
normalizedMessage.event_type = platformPushData.a !== undefined ? platformPushData.a : platformPushData.event_type;
normalizedMessage.file_path = platformPushData.file_path !== undefined ? platformPushData.file_path : "";
normalizedMessage.pic_url = platformPushData.pic_url !== undefined ? platformPushData.pic_url : "";
normalizedMessage.push_count = platformPushData.push_count !== undefined ? platformPushData.push_count : 1;
normalizedMessage.notification_style = platformPushData.notification_style;
normalizedMessage.storage_type = platformPushData.storage_type !== undefined ? platformPushData.storage_type : 1;
normalizedMessage.msg_type = platformPushData.msg_type;
normalizedMessage.person_name = platformPushData.nick_name;
normalizedMessage.person_id = platformPushData.person_id;
normalizedMessage.tfcard_status = platformPushData.tfcard_status;
normalizedMessage.user_type = platformPushData.user;
normalizedMessage.user_name = platformPushData.user_name;
normalizedMessage.station_guard_mode = platformPushData.arming;
normalizedMessage.station_current_mode = platformPushData.mode;
normalizedMessage.alarm_delay = platformPushData.alarm_delay;
normalizedMessage.sound_alarm = platformPushData.alarm !== undefined ? platformPushData.alarm === 1 ? true : false : undefined;
}
else if (device_1.Device.isBatteryDoorbell(normalizedMessage.type) || device_1.Device.isWiredDoorbellDual(normalizedMessage.type)) {
const batteryDoorbellPushData = payload.payload;
normalizedMessage.name = batteryDoorbellPushData.name ? batteryDoorbellPushData.name : "";
//Get family face names from Doorbell Dual "Family Recognition" event
if (batteryDoorbellPushData.objects !== undefined) {
normalizedMessage.person_name = batteryDoorbellPushData.objects.names !== undefined ? batteryDoorbellPushData.objects.names.join(",") : "";
}
if (normalizedMessage.person_name === "") {
normalizedMessage.person_name = batteryDoorbellPushData.nick_name;
}
normalizedMessage.channel = batteryDoorbellPushData.channel !== undefined ? batteryDoorbellPushData.channel : 0;
normalizedMessage.cipher = batteryDoorbellPushData.cipher !== undefined ? batteryDoorbellPushData.cipher : 0;
normalizedMessage.event_session = batteryDoorbellPushData.session_id !== undefined ? batteryDoorbellPushData.session_id : "";
normalizedMessage.event_type = batteryDoorbellPushData.event_type;
normalizedMessage.file_path = batteryDoorbellPushData.file_path !== undefined && batteryDoorbellPushData.file_path !== "" && batteryDoorbellPushData.channel !== undefined ? (0, utils_2.getAbsoluteFilePath)(normalizedMessage.type, batteryDoorbellPushData.channel, batteryDoorbellPushData.file_path) : "";
normalizedMessage.pic_url = batteryDoorbellPushData.pic_url !== undefined ? batteryDoorbellPushData.pic_url : "";
normalizedMessage.push_count = batteryDoorbellPushData.push_count !== undefined ? batteryDoorbellPushData.push_count : 1;
normalizedMessage.notification_style = batteryDoorbellPushData.notification_style;
}
else if (device_1.Device.isIndoorCamera(normalizedMessage.type) ||
device_1.Device.isSoloCameras(normalizedMessage.type) ||
device_1.Device.isWallLightCam(normalizedMessage.type) ||
device_1.Device.isOutdoorPanAndTiltCamera(normalizedMessage.type) ||
device_1.Device.isFloodLightT8420X(normalizedMessage.type, normalizedMessage.device_sn) ||
(device_1.Device.isFloodLight(normalizedMessage.type) && normalizedMessage.type !== types_1.DeviceType.FLOODLIGHT)) {
const indoorPushData = payload.payload;
normalizedMessage.name = indoorPushData.name ? indoorPushData.name : "";
normalizedMessage.channel = indoorPushData.channel;
normalizedMessage.cipher = indoorPushData.cipher;
normalizedMessage.event_session = indoorPushData.session_id;
normalizedMessage.event_type = indoorPushData.event_type;
//normalizedMessage.file_path = indoorPushData.file_path !== undefined && indoorPushData.file_path !== "" && indoorPushData.channel !== undefined ? getAbsoluteFilePath(normalizedMessage.type, indoorPushData.channel, indoorPushData.file_path) : "";
normalizedMessage.file_path = indoorPushData.file_path;
normalizedMessage.pic_url = indoorPushData.pic_url !== undefined ? indoorPushData.pic_url : "";
normalizedMessage.push_count = indoorPushData.push_count !== undefined ? indoorPushData.push_count : 1;
normalizedMessage.notification_style = indoorPushData.notification_style;
normalizedMessage.msg_type = indoorPushData.msg_type;
normalizedMessage.timeout = indoorPushData.timeout;
normalizedMessage.tfcard_status = indoorPushData.tfcard_status;
normalizedMessage.storage_type = indoorPushData.storage_type !== undefined ? indoorPushData.storage_type : 1;
normalizedMessage.unique_id = indoorPushData.unique_id;
}
else if (device_1.Device.isSmartSafe(normalizedMessage.type)) {
const smartSafePushData = payload.payload;
normalizedMessage.event_type = smartSafePushData.event_type;
normalizedMessage.event_value = smartSafePushData.event_value;
/*
event_value: {
type: 3, 3/4
action: 1,
figure_id: 0,
user_id: 0
}
*/
normalizedMessage.name = smartSafePushData.dev_name !== undefined ? smartSafePushData.dev_name : "";
/*normalizedMessage.short_user_id = smartSafePushData.short_user_id !== undefined ? smartSafePushData.short_user_id : "";
normalizedMessage.user_id = smartSafePushData.user_id !== undefined ? smartSafePushData.user_id : "";*/
}
else if (device_1.Device.isLock(normalizedMessage.type) && !device_1.Device.isLockWifiVideo(normalizedMessage.type)) {
const lockPushData = payload.payload;
normalizedMessage.event_type = lockPushData.event_type;
normalizedMessage.short_user_id = lockPushData.short_user_id !== undefined ? lockPushData.short_user_id : "";
normalizedMessage.user_id = lockPushData.user_id !== undefined ? lockPushData.user_id : "";
normalizedMessage.name = lockPushData.device_name !== undefined ? lockPushData.device_name : "";
normalizedMessage.person_name = lockPushData.nick_name !== undefined ? lockPushData.nick_name : "";
}
else if (device_1.Device.isGarageCamera(normalizedMessage.type)) {
const garageDoorPushData = payload.payload;
normalizedMessage.event_type = garageDoorPushData.event_type;
normalizedMessage.user_name = garageDoorPushData.user_name !== undefined ? garageDoorPushData.user_name : "";
normalizedMessage.door_id = garageDoorPushData.door_id !== undefined ? garageDoorPushData.door_id : -1;
normalizedMessage.name = garageDoorPushData.door_name !== undefined ? garageDoorPushData.door_name : "";
normalizedMessage.pic_url = garageDoorPushData.pic_url !== undefined ? garageDoorPushData.pic_url : "";
normalizedMessage.file_path = garageDoorPushData.file_path !== undefined ? garageDoorPushData.file_path : "";
normalizedMessage.storage_type = garageDoorPushData.storage_type !== undefined ? garageDoorPushData.storage_type : 1;
normalizedMessage.power = garageDoorPushData.power !== undefined ? garageDoorPushData.power : undefined;
}
else {
const cusPushData = payload.payload;
normalizedMessage.name = cusPushData.device_name && cusPushData.device_name !== null && cusPushData.device_name !== "" ? cusPushData.device_name : cusPushData.n ? cusPushData.n : cusPushData.name ? cusPushData.name : "";
normalizedMessage.channel = cusPushData.c ? cusPushData.c : cusPushData.channel;
normalizedMessage.cipher = cusPushData.k ? cusPushData.k : cusPushData.cipher;
normalizedMessage.event_session = cusPushData.session_id;
normalizedMessage.event_type = cusPushData.a ? cusPushData.a : cusPushData.event_type;
normalizedMessage.file_path = cusPushData.c !== undefined && cusPushData.p !== undefined && cusPushData.p !== "" ? (0, utils_2.getAbsoluteFilePath)(normalizedMessage.type, cusPushData.c, cusPushData.p) : cusPushData.file_path ? cusPushData.file_path : "";
normalizedMessage.pic_url = cusPushData.pic_url !== undefined ? cusPushData.pic_url : "";
normalizedMessage.push_count = cusPushData.push_count !== undefined ? cusPushData.push_count : 1;
normalizedMessage.notification_style = cusPushData.notification_style;
normalizedMessage.tfcard_status = cusPushData.tfcard;
normalizedMessage.alarm_delay_type = cusPushData.alarm_type;
normalizedMessage.alarm_delay = cusPushData.alarm_delay;
normalizedMessage.alarm_type = cusPushData.type;
normalizedMessage.sound_alarm = cusPushData.alarm !== undefined ? cusPushData.alarm === 1 ? true : false : undefined;
normalizedMessage.user_name = cusPushData.user_name;
normalizedMessage.user_type = cusPushData.user;
normalizedMessage.user_id = cusPushData.user_id;
normalizedMessage.short_user_id = cusPushData.short_user_id;
normalizedMessage.station_guard_mode = cusPushData.arming;
normalizedMessage.station_current_mode = cusPushData.mode;
normalizedMessage.person_name = cusPushData.f && cusPushData.f !== "" ? cusPushData.f : cusPushData.nick_name && cusPushData.nick_name ? cusPushData.nick_name : "";
normalizedMessage.sensor_open = cusPushData.e !== undefined ? cusPushData.e == "1" ? true : false : undefined;
normalizedMessage.device_online = cusPushData.m !== undefined ? cusPushData.m === 1 ? true : false : undefined;
try {
normalizedMessage.fetch_id = cusPushData.i !== undefined ? Number.parseInt(cusPushData.i) : undefined;
}
catch (err) {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error(`Normalize push message - Type ${types_1.DeviceType[normalizedMessage.type]} CusPushData - fetch_id - Error`, { error: (0, utils_3.getError)(error), message: message });
}
normalizedMessage.sense_id = cusPushData.j;
normalizedMessage.battery_powered = cusPushData.batt_powered !== undefined ? cusPushData.batt_powered === 1 ? true : false : undefined;
try {
normalizedMessage.battery_low = cusPushData.bat_low !== undefined ? Number.parseInt(cusPushData.bat_low) : undefined;
}
catch (err) {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error(`Normalize push message - Type ${types_1.DeviceType[normalizedMessage.type]} CusPushData - battery_low - Error`, { error: (0, utils_3.getError)(error), message: message });
}
normalizedMessage.storage_type = cusPushData.storage_type !== undefined ? cusPushData.storage_type : 1;
normalizedMessage.unique_id = cusPushData.unique_id;
normalizedMessage.automation_id = cusPushData.automation_id;
normalizedMessage.click_action = cusPushData.click_action;
normalizedMessage.news_id = cusPushData.news_id;
normalizedMessage.msg_type = cusPushData.msg_type;
if (device_1.Device.isStarlight4GLTE(normalizedMessage.type)) {
if (cusPushData.channel && cusPushData.channel !== null && cusPushData.channel !== undefined) {
normalizedMessage.channel = cusPushData.channel;
}
if (cusPushData.cipher && cusPushData.cipher !== null && cusPushData.cipher !== undefined) {
normalizedMessage.cipher = cusPushData.cipher;
}
if (cusPushData.event_type && cusPushData.event_type !== null && cusPushData.event_type !== undefined) {
normalizedMessage.event_type = cusPushData.event_type;
}
if (cusPushData.file_path && cusPushData.file_path !== null && cusPushData.file_path !== undefined) {
normalizedMessage.file_path = cusPushData.file_path;
}
normalizedMessage.msg_type = cusPushData.msg_type;
}
else if (device_1.Device.isSmartDrop(normalizedMessage.type)) {
try {
normalizedMessage.open = cusPushData.e !== undefined ? Number.parseInt(cusPushData.e) : 0;
}
catch (err) {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error(`Normalize push message - Type ${types_1.DeviceType[normalizedMessage.type]} CusPushData - open - Error`, { error: (0, utils_3.getError)(error), message: message });
}
try {
normalizedMessage.openType = cusPushData.r !== undefined ? Number.parseInt(cusPushData.r) : 0;
}
catch (err) {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error(`Normalize push message - Type ${types_1.DeviceType[normalizedMessage.type]} CusPushData - openType - Error`, { error: (0, utils_3.getError)(error), message: message });
}
normalizedMessage.person_name = cusPushData.p;
normalizedMessage.pin = cusPushData.u;
normalizedMessage.channel = cusPushData.channel !== undefined ? cusPushData.channel : 0;
normalizedMessage.cipher = cusPushData.cipher !== undefined ? cusPushData.cipher : 0;
normalizedMessage.event_session = cusPushData.session_id !== undefined ? cusPushData.session_id : "";
normalizedMessage.file_path = cusPushData.file_path !== undefined ? cusPushData.file_path : "";
}
}
}
}
else if (message.payload.doorbell !== undefined) {
const doorbellPushData = (0, utils_3.parseJSON)(message.payload.doorbell, logging_1.rootPushLogger);
if (doorbellPushData !== undefined) {
normalizedMessage.name = "Doorbell";
normalizedMessage.type = 5;
normalizedMessage.event_time = doorbellPushData.create_time !== undefined ? (0, utils_1.convertTimestampMs)(doorbellPushData.create_time) : doorbellPushData.create_time;
normalizedMessage.station_sn = doorbellPushData.device_sn;
normalizedMessage.device_sn = doorbellPushData.device_sn;
normalizedMessage.title = doorbellPushData.title;
normalizedMessage.content = doorbellPushData.content;
normalizedMessage.push_time = doorbellPushData.event_time !== undefined ? (0, utils_1.convertTimestampMs)(doorbellPushData.event_time) : doorbellPushData.event_time;
normalizedMessage.channel = doorbellPushData.channel;
normalizedMessage.cipher = doorbellPushData.cipher;
normalizedMessage.event_session = doorbellPushData.event_session;
normalizedMessage.event_type = doorbellPushData.event_type;
normalizedMessage.file_path = doorbellPushData.file_path;
normalizedMessage.pic_url = doorbellPushData.pic_url;
normalizedMessage.push_count = doorbellPushData.push_count !== undefined ? doorbellPushData.push_count : 1;
normalizedMessage.doorbell_url = doorbellPushData.url;
normalizedMessage.doorbell_url_ex = doorbellPushData.url_ex;
normalizedMessage.doorbell_video_url = doorbellPushData.video_url;
}
}
return normalizedMessage;
}
onMessage(message) {
logging_1.rootPushLogger.debug("Raw push message received", { message: message });
this.emit("raw message", message);
const normalizedMessage = this._normalizePushMessage(message);
logging_1.rootPushLogger.debug("Normalized push message received", { message: normalizedMessage });
this.emit("message", normalizedMessage);
}
getCurrentPushRetryDelay() {
const delay = this.retryDelay == 0 ? 5000 : this.retryDelay;
if (this.retryDelay < 60000)
this.retryDelay += 10000;
if (this.retryDelay >= 60000 && this.retryDelay < 600000)
this.retryDelay += 60000;
return delay;
}
setCredentials(credentials) {
this.credentials = credentials;
}
getCredentials() {
return this.credentials;
}
setPersistentIds(persistentIds) {
this.persistentIds = persistentIds;
}
getPersistentIds() {
return this.persistentIds;
}
async _open(renew = false, forceNew = false) {
if (forceNew || !this.credentials || Object.keys(this.credentials).length === 0 || (this.credentials && this.credentials.fidResponse && new Date().getTime() >= this.credentials.fidResponse.authToken.expiresAt)) {
logging_1.rootPushLogger.debug(`Create new push credentials...`, { credentials: this.credentials, renew: renew });
this.credentials = await this.createPushCredentials().catch(err => {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error("Create push credentials Error", { error: (0, utils_3.getError)(error), credentials: this.credentials, renew: renew });
return undefined;
});
}
else if (this.credentials && renew) {
logging_1.rootPushLogger.debug(`Renew push credentials...`, { credentials: this.credentials, renew: renew });
this.credentials = await this.renewPushCredentials(this.credentials).catch(err => {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error("Push credentials renew Error", { error: (0, utils_3.getError)(error), credentials: this.credentials, renew: renew });
return undefined;
});
}
else {
logging_1.rootPushLogger.debug(`Login with previous push credentials...`, { credentials: this.credentials });
this.credentials = await this.loginPushCredentials(this.credentials).catch(err => {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error("Push credentials login Error", { error: (0, utils_3.getError)(error), credentials: this.credentials, renew: renew });
return undefined;
});
}
if (this.credentials) {
this.emit("credential", this.credentials);
logging_1.rootPushLogger.debug("Push notification token received", { token: this.credentials.gcmResponse.token, credentials: this.credentials });
this.clearCredentialsTimeout();
this.credentialsTimeout = setTimeout(async () => {
logging_1.rootPushLogger.info("Push notification token is expiring, renew it.");
await this._open(true);
}, this.credentials.fidResponse.authToken.expiresAt - new Date().getTime() - 60000);
if (this.pushClient) {
this.pushClient.removeAllListeners();
}
logging_1.rootPushLogger.debug('Init PushClient with credentials', { credentials: this.credentials });
this.pushClient = await client_1.PushClient.init({
androidId: this.credentials.checkinResponse.androidId,
securityToken: this.credentials.checkinResponse.securityToken,
});
if (this.persistentIds)
this.pushClient.setPersistentIds(this.persistentIds);
const token = this.credentials.gcmResponse.token;
this.pushClient.on("connect", () => {
this.emit("connect", token);
this.connected = true;
this.connecting = false;
});
this.pushClient.on("close", () => {
this.emit("close");
this.connected = false;
this.connecting = false;
});
this.pushClient.on("message", (msg) => this.onMessage(msg));
this.pushClient.connect();
}
else {
this.emit("close");
this.connected = false;
this.connecting = false;
logging_1.rootPushLogger.error("Push notifications are disabled, because the registration failed!", { credentials: this.credentials, renew: renew });
}
}
async open() {
if (!this.connecting && !this.connected) {
this.connecting = true;
await this._open(false, true).catch((err) => {
const error = (0, error_2.ensureError)(err);
logging_1.rootPushLogger.error(`Got exception trying to initialize push notifications`, { error: (0, utils_3.getError)(error), credentials: this.credentials });
});
if (!this.credentials) {
this.clearRetryTimeout();
const delay = this.getCurrentPushRetryDelay();
logging_1.rootPushLogger.info(`Retry to register/login for push notification in ${delay / 1000} seconds...`);
this.retryTimeout = setTimeout(async () => {
logging_1.rootPushLogger.info(`Retry to register/login for push notification`);
await this.open();
}, delay);
}
else {
this.resetRetryTimeout();
this.emit("credential", this.credentials);
}
}
return this.credentials;
}
close() {
this.resetRetryTimeout();
this.clearCredentialsTimeout();
this.pushClient?.close();
}
clearCredentialsTimeout() {
if (this.credentialsTimeout) {
clearTimeout(this.credentialsTimeout);
this.credentialsTimeout = undefined;
}
}
clearRetryTimeout() {
if (this.retryTimeout) {
clearTimeout(this.retryTimeout);
this.retryTimeout = undefined;
}
}
resetRetryTimeout() {
this.clearRetryTimeout();
this.retryDelay = 0;
}
isConnected() {
return this.connected;
}
}
exports.PushNotificationService = PushNotificationService;
//# sourceMappingURL=service.js.map

File diff suppressed because one or more lines are too long

218
build/push/types.d.ts vendored Normal file
View File

@ -0,0 +1,218 @@
export declare enum CusPushEvent {
SECURITY = 1,
TFCARD = 2,
DOOR_SENSOR = 3,
CAM_STATE = 4,
GSENSOR = 5,
BATTERY_LOW = 6,
BATTERY_HOT = 7,
LIGHT_STATE = 8,
MODE_SWITCH = 9,
ALARM = 10,
BATTERY_FULL = 11,
REPEATER_RSSI_WEAK = 12,
UPGRADE_STATUS = 13,
MOTION_SENSOR_PIR = 14,
ALARM_DELAY = 16,
HUB_BATT_POWERED = 17,
SENSOR_NO_OPEN = 18,
SMART_DROP = 20
}
export declare enum CusPushAlarmType {
HUB_STOP = 0,
DEV_STOP = 1,
GSENSOR = 2,
PIR = 3,
APP = 4,
HOT = 5,
DOOR = 6,
CAMERA = 7,
MOTION_SENSOR = 8,
CAMERA_GSENSOR = 9,
CAMERA_APP = 10,
CAMERA_LINKAGE = 11,
HUB_LINKAGE = 12,
HUB_KEYPAD_PANIC_BUTTON = 13,
HUB_KEYPAD_EMERGENCY_CODE = 14,
HUB_STOP_BY_KEYPAD = 15,
HUB_STOP_BY_APP = 16,
HUB_STOP_BY_HUB = 17,
HUB_KEYPAD_CUSTOM_NOT_MAP = 18
}
export declare enum CusPushMode {
SWITCH_FROM_KEYPAD = 1,
SWITCH_FROM_APP = 2,
SWITCH = 9
}
export declare enum ServerPushEvent {
INVITE_DEVICE = 10300,
REMOVE_DEVICE = 10200,
REMOVE_HOMEBASE = 10100,
VERIFICATION = 10500,
WEB_ACTION = 10800,
ALARM_NOTIFY = 10900,
ALARM_GUEST_NOTIFY = 11000,
HOUSE_ADDED = 11400,
HOUSE_INVITE = 11300,
HOUSE_REMOVE = 11200
}
export declare enum DoorbellPushEvent {
BACKGROUND_ACTIVE = 3100,
MOTION_DETECTION = 3101,
FACE_DETECTION = 3102,
PRESS_DOORBELL = 3103,
PET_DETECTION = 3106,
VEHICLE_DETECTION = 3107,
PACKAGE_DELIVERED = 3301,
PACKAGE_TAKEN = 3302,
FAMILY_DETECTION = 3303,
PACKAGE_STRANDED = 3304,
SOMEONE_LOITERING = 3305,
RADAR_MOTION_DETECTION = 3306,
AWAY_FROM_HOME = 3307,
RADAR_DETECTION = 3308
}
export declare enum LockPushEvent {
MANUAL_UNLOCK = 257,
AUTO_UNLOCK = 258,
PW_UNLOCK = 259,
FINGERPRINT_UNLOCK = 260,
APP_UNLOCK = 261,
MANUAL_LOCK = 262,
KEYPAD_LOCK = 263,
APP_LOCK = 264,
AUTO_LOCK = 265,
PW_LOCK = 266,
FINGER_LOCK = 267,
TEMPORARY_PW_LOCK = 268,
TEMPORARY_PW_UNLOCK = 269,
LOW_POWER = 513,
VERY_LOW_POWER = 514,
MULTIPLE_ERRORS = 515,
LOCK_OFFLINE = 516,
MECHANICAL_ANOMALY = 517,
VIOLENT_DESTRUCTION = 518,
LOCK_MECHANICAL_ANOMALY = 519,
DOOR_OPEN_LEFT = 520,
DOOR_TAMPER = 521,
DOOR_STATE_ERROR = 522,
STATUS_CHANGE = 769,
OTA_STATUS = 770,
LOCK_ONLINE = 771
}
export declare enum IndoorPushEvent {
MOTION_DETECTION = 3101,
FACE_DETECTION = 3102,
CRYING_DETECTION = 3104,
SOUND_DETECTION = 3105,
PET_DETECTION = 3106,
VEHICLE_DETECTION = 3107
}
export declare enum GarageDoorPushEvent {
CLOSED_DOOR_BY_APP = 1,
OPEN_DOOR_BY_APP = 2,
CLOSED_DOOR_WITHOUT_APP = 3,
OPEN_DOOR_WITHOUT_APP = 4,
TIMEOUT_DOOR_OPEN_WARNING = 5,
TIMEOUT_CLOSED_DOOR = 6,
TIMEOUT_DOOR_OPEN_WARNING_MINUTES = 7,
LOW_BATTERY = 8
}
export declare enum SmartSafeEvent {
ALARM_911 = 1946161152,
LOCK_STATUS = 1946161153,
SHAKE_ALARM = 1946161154,
BATTERY_STATUS = 1946161155,
LONG_TIME_NOT_CLOSE = 1946161156,
FORCE_FIGURE = 1946161157,
LOW_POWER = 1946161158,
INPUT_ERR_MAX = 1946161159,
SHUTDOWN = 1946161160
}
export declare enum HB3PairedDevicePushEvent {
MOTION_DETECTION = 3101,
FACE_DETECTION = 3102,
PRESS_DOORBELL = 3103,
CRYING_DETECTION = 3104,
SOUND_DETECTION = 3105,
PET_DETECTION = 3106,
VEHICLE_DETECTION = 3107,
DOG_DETECTION = 3108,
DOG_LICK_DETECTION = 3109,
DOG_POOP_DETECTION = 3110,
IDENTITY_PERSON_DETECTION = 3111,
STRANGER_PERSON_DETECTION = 3112
}
export declare enum HB3PairedDeviceMessageType {
SECURITY_EVT = 1,
TFCARD_EVT = 2,
DOOR_SENSOR_EVT = 3,
CAM_STATE_EVT = 4,
GSENSOR_EVT = 5,
BATTERY_LOW_EVT = 6,
BATTERY_HOT_EVT = 7,
LIGHT_STATE_EVT = 8,
ARMING_EVT = 9,
ALARM_EVT = 10,
BATTERY_FULL_EVT = 11,
REPEATER_RSSI_WEAK_EVT = 12,
UPGRADE_STATUS = 13,
MOTION_SENSOR_EVT = 14,
BAT_DOORBELL_EVT = 15,
ALARM_DELAY_EVT = 16,
HUB_BATT_POWERED_EVT = 17,
INDOOR_EVT = 18,
SMARTLOCK_EVT = 19,
LOCK_EVT = 20,
BBM_SOCK_EVT = 21,
DOOR_STATUS_EVT = 22,
HHD_EVT = 23
}
export declare enum HB3HDDType {
NODISK = 0,
READY = 1,
PROCESSING = 2,
NO_PARTED = 3,
NO_ANKER_DISK = 4,
NOT_FORMAT = 5,
OTHER_USER_DISK = 6,
BAD = 7,
WAIT_NETWOR = 8,
PARTED_DONE = 9,
FULL = 32
}
export declare enum IndoorPushMessageType {
INDOOR = 18,
TFCARD = 2
}
export declare enum NotificationStyle {
TEXT = 1,
THUMB = 2,
ALL = 3
}
export declare enum AlarmAction {
CANCEL_APP = 0,
CANCEL_NOLIGHT = 1
}
export declare enum SmartDropPushEvent {
LOW_BATTERY = 6,
OVERHEATING_WARNING = 7,
TAMPERED_WARNING = 10,
BATTERY_FULLY_CHARGED = 11,
PERSON_DETECTED = 3102
}
export declare enum SmartDropOpen {
OPEN = 1,
CLOSED = 2,
LID_STUCK = 3,
PIN_INCORRECT = 4,
LEFT_OPENED = 10,
LOW_TEMPERATURE_WARNING = 11
}
export declare enum SmartDropOpenedBy {
APP = 1,
PIN = 2,
WITHOUT_KEY = 3,
EMERGENCY_RELEASE_BUTTON = 4,
KEY = 5
}

242
build/push/types.js Normal file
View File

@ -0,0 +1,242 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SmartDropOpenedBy = exports.SmartDropOpen = exports.SmartDropPushEvent = exports.AlarmAction = exports.NotificationStyle = exports.IndoorPushMessageType = exports.HB3HDDType = exports.HB3PairedDeviceMessageType = exports.HB3PairedDevicePushEvent = exports.SmartSafeEvent = exports.GarageDoorPushEvent = exports.IndoorPushEvent = exports.LockPushEvent = exports.DoorbellPushEvent = exports.ServerPushEvent = exports.CusPushMode = exports.CusPushAlarmType = exports.CusPushEvent = void 0;
var CusPushEvent;
(function (CusPushEvent) {
CusPushEvent[CusPushEvent["SECURITY"] = 1] = "SECURITY";
CusPushEvent[CusPushEvent["TFCARD"] = 2] = "TFCARD";
CusPushEvent[CusPushEvent["DOOR_SENSOR"] = 3] = "DOOR_SENSOR";
CusPushEvent[CusPushEvent["CAM_STATE"] = 4] = "CAM_STATE";
CusPushEvent[CusPushEvent["GSENSOR"] = 5] = "GSENSOR";
CusPushEvent[CusPushEvent["BATTERY_LOW"] = 6] = "BATTERY_LOW";
CusPushEvent[CusPushEvent["BATTERY_HOT"] = 7] = "BATTERY_HOT";
CusPushEvent[CusPushEvent["LIGHT_STATE"] = 8] = "LIGHT_STATE";
CusPushEvent[CusPushEvent["MODE_SWITCH"] = 9] = "MODE_SWITCH";
CusPushEvent[CusPushEvent["ALARM"] = 10] = "ALARM";
CusPushEvent[CusPushEvent["BATTERY_FULL"] = 11] = "BATTERY_FULL";
CusPushEvent[CusPushEvent["REPEATER_RSSI_WEAK"] = 12] = "REPEATER_RSSI_WEAK";
CusPushEvent[CusPushEvent["UPGRADE_STATUS"] = 13] = "UPGRADE_STATUS";
CusPushEvent[CusPushEvent["MOTION_SENSOR_PIR"] = 14] = "MOTION_SENSOR_PIR";
CusPushEvent[CusPushEvent["ALARM_DELAY"] = 16] = "ALARM_DELAY";
CusPushEvent[CusPushEvent["HUB_BATT_POWERED"] = 17] = "HUB_BATT_POWERED";
CusPushEvent[CusPushEvent["SENSOR_NO_OPEN"] = 18] = "SENSOR_NO_OPEN";
CusPushEvent[CusPushEvent["SMART_DROP"] = 20] = "SMART_DROP";
})(CusPushEvent || (exports.CusPushEvent = CusPushEvent = {}));
var CusPushAlarmType;
(function (CusPushAlarmType) {
CusPushAlarmType[CusPushAlarmType["HUB_STOP"] = 0] = "HUB_STOP";
CusPushAlarmType[CusPushAlarmType["DEV_STOP"] = 1] = "DEV_STOP";
CusPushAlarmType[CusPushAlarmType["GSENSOR"] = 2] = "GSENSOR";
CusPushAlarmType[CusPushAlarmType["PIR"] = 3] = "PIR";
CusPushAlarmType[CusPushAlarmType["APP"] = 4] = "APP";
CusPushAlarmType[CusPushAlarmType["HOT"] = 5] = "HOT";
CusPushAlarmType[CusPushAlarmType["DOOR"] = 6] = "DOOR";
CusPushAlarmType[CusPushAlarmType["CAMERA"] = 7] = "CAMERA";
CusPushAlarmType[CusPushAlarmType["MOTION_SENSOR"] = 8] = "MOTION_SENSOR";
CusPushAlarmType[CusPushAlarmType["CAMERA_GSENSOR"] = 9] = "CAMERA_GSENSOR";
CusPushAlarmType[CusPushAlarmType["CAMERA_APP"] = 10] = "CAMERA_APP";
CusPushAlarmType[CusPushAlarmType["CAMERA_LINKAGE"] = 11] = "CAMERA_LINKAGE";
CusPushAlarmType[CusPushAlarmType["HUB_LINKAGE"] = 12] = "HUB_LINKAGE";
CusPushAlarmType[CusPushAlarmType["HUB_KEYPAD_PANIC_BUTTON"] = 13] = "HUB_KEYPAD_PANIC_BUTTON";
CusPushAlarmType[CusPushAlarmType["HUB_KEYPAD_EMERGENCY_CODE"] = 14] = "HUB_KEYPAD_EMERGENCY_CODE";
CusPushAlarmType[CusPushAlarmType["HUB_STOP_BY_KEYPAD"] = 15] = "HUB_STOP_BY_KEYPAD";
CusPushAlarmType[CusPushAlarmType["HUB_STOP_BY_APP"] = 16] = "HUB_STOP_BY_APP";
CusPushAlarmType[CusPushAlarmType["HUB_STOP_BY_HUB"] = 17] = "HUB_STOP_BY_HUB";
CusPushAlarmType[CusPushAlarmType["HUB_KEYPAD_CUSTOM_NOT_MAP"] = 18] = "HUB_KEYPAD_CUSTOM_NOT_MAP";
})(CusPushAlarmType || (exports.CusPushAlarmType = CusPushAlarmType = {}));
var CusPushMode;
(function (CusPushMode) {
CusPushMode[CusPushMode["SWITCH_FROM_KEYPAD"] = 1] = "SWITCH_FROM_KEYPAD";
CusPushMode[CusPushMode["SWITCH_FROM_APP"] = 2] = "SWITCH_FROM_APP";
CusPushMode[CusPushMode["SWITCH"] = 9] = "SWITCH";
})(CusPushMode || (exports.CusPushMode = CusPushMode = {}));
var ServerPushEvent;
(function (ServerPushEvent) {
ServerPushEvent[ServerPushEvent["INVITE_DEVICE"] = 10300] = "INVITE_DEVICE";
ServerPushEvent[ServerPushEvent["REMOVE_DEVICE"] = 10200] = "REMOVE_DEVICE";
ServerPushEvent[ServerPushEvent["REMOVE_HOMEBASE"] = 10100] = "REMOVE_HOMEBASE";
ServerPushEvent[ServerPushEvent["VERIFICATION"] = 10500] = "VERIFICATION";
ServerPushEvent[ServerPushEvent["WEB_ACTION"] = 10800] = "WEB_ACTION";
ServerPushEvent[ServerPushEvent["ALARM_NOTIFY"] = 10900] = "ALARM_NOTIFY";
ServerPushEvent[ServerPushEvent["ALARM_GUEST_NOTIFY"] = 11000] = "ALARM_GUEST_NOTIFY";
ServerPushEvent[ServerPushEvent["HOUSE_ADDED"] = 11400] = "HOUSE_ADDED";
ServerPushEvent[ServerPushEvent["HOUSE_INVITE"] = 11300] = "HOUSE_INVITE";
ServerPushEvent[ServerPushEvent["HOUSE_REMOVE"] = 11200] = "HOUSE_REMOVE";
})(ServerPushEvent || (exports.ServerPushEvent = ServerPushEvent = {}));
var DoorbellPushEvent;
(function (DoorbellPushEvent) {
DoorbellPushEvent[DoorbellPushEvent["BACKGROUND_ACTIVE"] = 3100] = "BACKGROUND_ACTIVE";
DoorbellPushEvent[DoorbellPushEvent["MOTION_DETECTION"] = 3101] = "MOTION_DETECTION";
DoorbellPushEvent[DoorbellPushEvent["FACE_DETECTION"] = 3102] = "FACE_DETECTION";
DoorbellPushEvent[DoorbellPushEvent["PRESS_DOORBELL"] = 3103] = "PRESS_DOORBELL";
//OFFLINE = 3106,
DoorbellPushEvent[DoorbellPushEvent["PET_DETECTION"] = 3106] = "PET_DETECTION";
//ONLINE = 3107,
DoorbellPushEvent[DoorbellPushEvent["VEHICLE_DETECTION"] = 3107] = "VEHICLE_DETECTION";
DoorbellPushEvent[DoorbellPushEvent["PACKAGE_DELIVERED"] = 3301] = "PACKAGE_DELIVERED";
DoorbellPushEvent[DoorbellPushEvent["PACKAGE_TAKEN"] = 3302] = "PACKAGE_TAKEN";
DoorbellPushEvent[DoorbellPushEvent["FAMILY_DETECTION"] = 3303] = "FAMILY_DETECTION";
DoorbellPushEvent[DoorbellPushEvent["PACKAGE_STRANDED"] = 3304] = "PACKAGE_STRANDED";
DoorbellPushEvent[DoorbellPushEvent["SOMEONE_LOITERING"] = 3305] = "SOMEONE_LOITERING";
DoorbellPushEvent[DoorbellPushEvent["RADAR_MOTION_DETECTION"] = 3306] = "RADAR_MOTION_DETECTION";
DoorbellPushEvent[DoorbellPushEvent["AWAY_FROM_HOME"] = 3307] = "AWAY_FROM_HOME";
DoorbellPushEvent[DoorbellPushEvent["RADAR_DETECTION"] = 3308] = "RADAR_DETECTION";
})(DoorbellPushEvent || (exports.DoorbellPushEvent = DoorbellPushEvent = {}));
var LockPushEvent;
(function (LockPushEvent) {
LockPushEvent[LockPushEvent["MANUAL_UNLOCK"] = 257] = "MANUAL_UNLOCK";
LockPushEvent[LockPushEvent["AUTO_UNLOCK"] = 258] = "AUTO_UNLOCK";
LockPushEvent[LockPushEvent["PW_UNLOCK"] = 259] = "PW_UNLOCK";
LockPushEvent[LockPushEvent["FINGERPRINT_UNLOCK"] = 260] = "FINGERPRINT_UNLOCK";
LockPushEvent[LockPushEvent["APP_UNLOCK"] = 261] = "APP_UNLOCK";
LockPushEvent[LockPushEvent["MANUAL_LOCK"] = 262] = "MANUAL_LOCK";
LockPushEvent[LockPushEvent["KEYPAD_LOCK"] = 263] = "KEYPAD_LOCK";
LockPushEvent[LockPushEvent["APP_LOCK"] = 264] = "APP_LOCK";
LockPushEvent[LockPushEvent["AUTO_LOCK"] = 265] = "AUTO_LOCK";
LockPushEvent[LockPushEvent["PW_LOCK"] = 266] = "PW_LOCK";
LockPushEvent[LockPushEvent["FINGER_LOCK"] = 267] = "FINGER_LOCK";
LockPushEvent[LockPushEvent["TEMPORARY_PW_LOCK"] = 268] = "TEMPORARY_PW_LOCK";
LockPushEvent[LockPushEvent["TEMPORARY_PW_UNLOCK"] = 269] = "TEMPORARY_PW_UNLOCK";
LockPushEvent[LockPushEvent["LOW_POWER"] = 513] = "LOW_POWER";
LockPushEvent[LockPushEvent["VERY_LOW_POWER"] = 514] = "VERY_LOW_POWER";
LockPushEvent[LockPushEvent["MULTIPLE_ERRORS"] = 515] = "MULTIPLE_ERRORS";
LockPushEvent[LockPushEvent["LOCK_OFFLINE"] = 516] = "LOCK_OFFLINE";
LockPushEvent[LockPushEvent["MECHANICAL_ANOMALY"] = 517] = "MECHANICAL_ANOMALY";
LockPushEvent[LockPushEvent["VIOLENT_DESTRUCTION"] = 518] = "VIOLENT_DESTRUCTION";
LockPushEvent[LockPushEvent["LOCK_MECHANICAL_ANOMALY"] = 519] = "LOCK_MECHANICAL_ANOMALY";
LockPushEvent[LockPushEvent["DOOR_OPEN_LEFT"] = 520] = "DOOR_OPEN_LEFT";
LockPushEvent[LockPushEvent["DOOR_TAMPER"] = 521] = "DOOR_TAMPER";
LockPushEvent[LockPushEvent["DOOR_STATE_ERROR"] = 522] = "DOOR_STATE_ERROR";
LockPushEvent[LockPushEvent["STATUS_CHANGE"] = 769] = "STATUS_CHANGE";
LockPushEvent[LockPushEvent["OTA_STATUS"] = 770] = "OTA_STATUS";
LockPushEvent[LockPushEvent["LOCK_ONLINE"] = 771] = "LOCK_ONLINE";
})(LockPushEvent || (exports.LockPushEvent = LockPushEvent = {}));
var IndoorPushEvent;
(function (IndoorPushEvent) {
IndoorPushEvent[IndoorPushEvent["MOTION_DETECTION"] = 3101] = "MOTION_DETECTION";
IndoorPushEvent[IndoorPushEvent["FACE_DETECTION"] = 3102] = "FACE_DETECTION";
IndoorPushEvent[IndoorPushEvent["CRYING_DETECTION"] = 3104] = "CRYING_DETECTION";
IndoorPushEvent[IndoorPushEvent["SOUND_DETECTION"] = 3105] = "SOUND_DETECTION";
IndoorPushEvent[IndoorPushEvent["PET_DETECTION"] = 3106] = "PET_DETECTION";
IndoorPushEvent[IndoorPushEvent["VEHICLE_DETECTION"] = 3107] = "VEHICLE_DETECTION";
})(IndoorPushEvent || (exports.IndoorPushEvent = IndoorPushEvent = {}));
var GarageDoorPushEvent;
(function (GarageDoorPushEvent) {
GarageDoorPushEvent[GarageDoorPushEvent["CLOSED_DOOR_BY_APP"] = 1] = "CLOSED_DOOR_BY_APP";
GarageDoorPushEvent[GarageDoorPushEvent["OPEN_DOOR_BY_APP"] = 2] = "OPEN_DOOR_BY_APP";
GarageDoorPushEvent[GarageDoorPushEvent["CLOSED_DOOR_WITHOUT_APP"] = 3] = "CLOSED_DOOR_WITHOUT_APP";
GarageDoorPushEvent[GarageDoorPushEvent["OPEN_DOOR_WITHOUT_APP"] = 4] = "OPEN_DOOR_WITHOUT_APP";
GarageDoorPushEvent[GarageDoorPushEvent["TIMEOUT_DOOR_OPEN_WARNING"] = 5] = "TIMEOUT_DOOR_OPEN_WARNING";
GarageDoorPushEvent[GarageDoorPushEvent["TIMEOUT_CLOSED_DOOR"] = 6] = "TIMEOUT_CLOSED_DOOR";
GarageDoorPushEvent[GarageDoorPushEvent["TIMEOUT_DOOR_OPEN_WARNING_MINUTES"] = 7] = "TIMEOUT_DOOR_OPEN_WARNING_MINUTES";
GarageDoorPushEvent[GarageDoorPushEvent["LOW_BATTERY"] = 8] = "LOW_BATTERY";
})(GarageDoorPushEvent || (exports.GarageDoorPushEvent = GarageDoorPushEvent = {}));
var SmartSafeEvent;
(function (SmartSafeEvent) {
SmartSafeEvent[SmartSafeEvent["ALARM_911"] = 1946161152] = "ALARM_911";
SmartSafeEvent[SmartSafeEvent["LOCK_STATUS"] = 1946161153] = "LOCK_STATUS";
SmartSafeEvent[SmartSafeEvent["SHAKE_ALARM"] = 1946161154] = "SHAKE_ALARM";
SmartSafeEvent[SmartSafeEvent["BATTERY_STATUS"] = 1946161155] = "BATTERY_STATUS";
SmartSafeEvent[SmartSafeEvent["LONG_TIME_NOT_CLOSE"] = 1946161156] = "LONG_TIME_NOT_CLOSE";
SmartSafeEvent[SmartSafeEvent["FORCE_FIGURE"] = 1946161157] = "FORCE_FIGURE";
SmartSafeEvent[SmartSafeEvent["LOW_POWER"] = 1946161158] = "LOW_POWER";
SmartSafeEvent[SmartSafeEvent["INPUT_ERR_MAX"] = 1946161159] = "INPUT_ERR_MAX";
SmartSafeEvent[SmartSafeEvent["SHUTDOWN"] = 1946161160] = "SHUTDOWN";
})(SmartSafeEvent || (exports.SmartSafeEvent = SmartSafeEvent = {}));
var HB3PairedDevicePushEvent;
(function (HB3PairedDevicePushEvent) {
HB3PairedDevicePushEvent[HB3PairedDevicePushEvent["MOTION_DETECTION"] = 3101] = "MOTION_DETECTION";
HB3PairedDevicePushEvent[HB3PairedDevicePushEvent["FACE_DETECTION"] = 3102] = "FACE_DETECTION";
HB3PairedDevicePushEvent[HB3PairedDevicePushEvent["PRESS_DOORBELL"] = 3103] = "PRESS_DOORBELL";
HB3PairedDevicePushEvent[HB3PairedDevicePushEvent["CRYING_DETECTION"] = 3104] = "CRYING_DETECTION";
HB3PairedDevicePushEvent[HB3PairedDevicePushEvent["SOUND_DETECTION"] = 3105] = "SOUND_DETECTION";
HB3PairedDevicePushEvent[HB3PairedDevicePushEvent["PET_DETECTION"] = 3106] = "PET_DETECTION";
HB3PairedDevicePushEvent[HB3PairedDevicePushEvent["VEHICLE_DETECTION"] = 3107] = "VEHICLE_DETECTION";
HB3PairedDevicePushEvent[HB3PairedDevicePushEvent["DOG_DETECTION"] = 3108] = "DOG_DETECTION";
HB3PairedDevicePushEvent[HB3PairedDevicePushEvent["DOG_LICK_DETECTION"] = 3109] = "DOG_LICK_DETECTION";
HB3PairedDevicePushEvent[HB3PairedDevicePushEvent["DOG_POOP_DETECTION"] = 3110] = "DOG_POOP_DETECTION";
HB3PairedDevicePushEvent[HB3PairedDevicePushEvent["IDENTITY_PERSON_DETECTION"] = 3111] = "IDENTITY_PERSON_DETECTION";
HB3PairedDevicePushEvent[HB3PairedDevicePushEvent["STRANGER_PERSON_DETECTION"] = 3112] = "STRANGER_PERSON_DETECTION";
})(HB3PairedDevicePushEvent || (exports.HB3PairedDevicePushEvent = HB3PairedDevicePushEvent = {}));
var HB3PairedDeviceMessageType;
(function (HB3PairedDeviceMessageType) {
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["SECURITY_EVT"] = 1] = "SECURITY_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["TFCARD_EVT"] = 2] = "TFCARD_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["DOOR_SENSOR_EVT"] = 3] = "DOOR_SENSOR_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["CAM_STATE_EVT"] = 4] = "CAM_STATE_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["GSENSOR_EVT"] = 5] = "GSENSOR_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["BATTERY_LOW_EVT"] = 6] = "BATTERY_LOW_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["BATTERY_HOT_EVT"] = 7] = "BATTERY_HOT_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["LIGHT_STATE_EVT"] = 8] = "LIGHT_STATE_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["ARMING_EVT"] = 9] = "ARMING_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["ALARM_EVT"] = 10] = "ALARM_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["BATTERY_FULL_EVT"] = 11] = "BATTERY_FULL_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["REPEATER_RSSI_WEAK_EVT"] = 12] = "REPEATER_RSSI_WEAK_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["UPGRADE_STATUS"] = 13] = "UPGRADE_STATUS";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["MOTION_SENSOR_EVT"] = 14] = "MOTION_SENSOR_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["BAT_DOORBELL_EVT"] = 15] = "BAT_DOORBELL_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["ALARM_DELAY_EVT"] = 16] = "ALARM_DELAY_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["HUB_BATT_POWERED_EVT"] = 17] = "HUB_BATT_POWERED_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["INDOOR_EVT"] = 18] = "INDOOR_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["SMARTLOCK_EVT"] = 19] = "SMARTLOCK_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["LOCK_EVT"] = 20] = "LOCK_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["BBM_SOCK_EVT"] = 21] = "BBM_SOCK_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["DOOR_STATUS_EVT"] = 22] = "DOOR_STATUS_EVT";
HB3PairedDeviceMessageType[HB3PairedDeviceMessageType["HHD_EVT"] = 23] = "HHD_EVT";
})(HB3PairedDeviceMessageType || (exports.HB3PairedDeviceMessageType = HB3PairedDeviceMessageType = {}));
var HB3HDDType;
(function (HB3HDDType) {
HB3HDDType[HB3HDDType["NODISK"] = 0] = "NODISK";
HB3HDDType[HB3HDDType["READY"] = 1] = "READY";
HB3HDDType[HB3HDDType["PROCESSING"] = 2] = "PROCESSING";
HB3HDDType[HB3HDDType["NO_PARTED"] = 3] = "NO_PARTED";
HB3HDDType[HB3HDDType["NO_ANKER_DISK"] = 4] = "NO_ANKER_DISK";
HB3HDDType[HB3HDDType["NOT_FORMAT"] = 5] = "NOT_FORMAT";
HB3HDDType[HB3HDDType["OTHER_USER_DISK"] = 6] = "OTHER_USER_DISK";
HB3HDDType[HB3HDDType["BAD"] = 7] = "BAD";
HB3HDDType[HB3HDDType["WAIT_NETWOR"] = 8] = "WAIT_NETWOR";
HB3HDDType[HB3HDDType["PARTED_DONE"] = 9] = "PARTED_DONE";
HB3HDDType[HB3HDDType["FULL"] = 32] = "FULL";
})(HB3HDDType || (exports.HB3HDDType = HB3HDDType = {}));
var IndoorPushMessageType;
(function (IndoorPushMessageType) {
IndoorPushMessageType[IndoorPushMessageType["INDOOR"] = 18] = "INDOOR";
IndoorPushMessageType[IndoorPushMessageType["TFCARD"] = 2] = "TFCARD";
})(IndoorPushMessageType || (exports.IndoorPushMessageType = IndoorPushMessageType = {}));
var NotificationStyle;
(function (NotificationStyle) {
NotificationStyle[NotificationStyle["TEXT"] = 1] = "TEXT";
NotificationStyle[NotificationStyle["THUMB"] = 2] = "THUMB";
NotificationStyle[NotificationStyle["ALL"] = 3] = "ALL";
})(NotificationStyle || (exports.NotificationStyle = NotificationStyle = {}));
var AlarmAction;
(function (AlarmAction) {
AlarmAction[AlarmAction["CANCEL_APP"] = 0] = "CANCEL_APP";
AlarmAction[AlarmAction["CANCEL_NOLIGHT"] = 1] = "CANCEL_NOLIGHT";
})(AlarmAction || (exports.AlarmAction = AlarmAction = {}));
var SmartDropPushEvent;
(function (SmartDropPushEvent) {
SmartDropPushEvent[SmartDropPushEvent["LOW_BATTERY"] = 6] = "LOW_BATTERY";
SmartDropPushEvent[SmartDropPushEvent["OVERHEATING_WARNING"] = 7] = "OVERHEATING_WARNING";
SmartDropPushEvent[SmartDropPushEvent["TAMPERED_WARNING"] = 10] = "TAMPERED_WARNING";
SmartDropPushEvent[SmartDropPushEvent["BATTERY_FULLY_CHARGED"] = 11] = "BATTERY_FULLY_CHARGED";
SmartDropPushEvent[SmartDropPushEvent["PERSON_DETECTED"] = 3102] = "PERSON_DETECTED";
})(SmartDropPushEvent || (exports.SmartDropPushEvent = SmartDropPushEvent = {}));
var SmartDropOpen;
(function (SmartDropOpen) {
SmartDropOpen[SmartDropOpen["OPEN"] = 1] = "OPEN";
SmartDropOpen[SmartDropOpen["CLOSED"] = 2] = "CLOSED";
SmartDropOpen[SmartDropOpen["LID_STUCK"] = 3] = "LID_STUCK";
SmartDropOpen[SmartDropOpen["PIN_INCORRECT"] = 4] = "PIN_INCORRECT";
SmartDropOpen[SmartDropOpen["LEFT_OPENED"] = 10] = "LEFT_OPENED";
SmartDropOpen[SmartDropOpen["LOW_TEMPERATURE_WARNING"] = 11] = "LOW_TEMPERATURE_WARNING";
})(SmartDropOpen || (exports.SmartDropOpen = SmartDropOpen = {}));
var SmartDropOpenedBy;
(function (SmartDropOpenedBy) {
SmartDropOpenedBy[SmartDropOpenedBy["APP"] = 1] = "APP";
SmartDropOpenedBy[SmartDropOpenedBy["PIN"] = 2] = "PIN";
SmartDropOpenedBy[SmartDropOpenedBy["WITHOUT_KEY"] = 3] = "WITHOUT_KEY";
SmartDropOpenedBy[SmartDropOpenedBy["EMERGENCY_RELEASE_BUTTON"] = 4] = "EMERGENCY_RELEASE_BUTTON";
SmartDropOpenedBy[SmartDropOpenedBy["KEY"] = 5] = "KEY";
})(SmartDropOpenedBy || (exports.SmartDropOpenedBy = SmartDropOpenedBy = {}));
//# sourceMappingURL=types.js.map

1
build/push/types.js.map Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/push/types.ts"],"names":[],"mappings":"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"}

7
build/push/utils.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
import { CheckinResponse } from "./models";
export declare const VALID_FID_PATTERN: RegExp;
export declare function generateFid(): string;
export declare const buildCheckinRequest: () => Promise<Uint8Array>;
export declare const parseCheckinResponse: (data: Buffer) => Promise<CheckinResponse>;
export declare const sleep: (ms: number) => Promise<void>;
export declare function convertTimestampMs(timestamp: number): number;

106
build/push/utils.js Normal file
View File

@ -0,0 +1,106 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.sleep = exports.parseCheckinResponse = exports.buildCheckinRequest = exports.VALID_FID_PATTERN = void 0;
exports.generateFid = generateFid;
exports.convertTimestampMs = convertTimestampMs;
const crypto_1 = require("crypto");
const path = __importStar(require("path"));
const protobufjs_1 = require("protobufjs");
const error_1 = require("./error");
const logging_1 = require("../logging");
exports.VALID_FID_PATTERN = /^[cdef][\w-]{21}$/;
function generateFid() {
const fidByteArray = new Uint8Array(17);
fidByteArray.set((0, crypto_1.randomBytes)(fidByteArray.length));
// Replace the first 4 random bits with the constant FID header of 0b0111.
fidByteArray[0] = 0b01110000 + (fidByteArray[0] % 0b00010000);
const b64 = Buffer.from(fidByteArray).toString("base64");
const b64_safe = b64.replace(/\+/g, "-").replace(/\//g, "_");
const fid = b64_safe.substr(0, 22);
if (exports.VALID_FID_PATTERN.test(fid)) {
logging_1.rootPushLogger.info('generateFid', fid);
return fid;
}
throw new error_1.FidGenerationError("Generated invalid FID", { context: { fid: fid } });
}
const buildCheckinRequest = async () => {
const root = await (0, protobufjs_1.load)(path.join(__dirname, "./proto/checkin.proto"));
const CheckinRequestModel = root.lookupType("CheckinRequest");
const payload = {
imei: "109269993813709",
androidId: 0,
checkin: {
build: {
fingerprint: "google/razor/flo:5.0.1/LRX22C/1602158:user/release-keys",
hardware: "flo",
brand: "google",
radio: "FLO-04.04",
clientId: "android-google",
},
lastCheckinMs: 0,
},
locale: "en",
loggingId: 1234567890,
macAddress: ["A1B2C3D4E5F6"],
meid: "109269993813709",
accountCookie: [],
timeZone: "GMT",
version: 3,
otaCert: ["71Q6Rn2DDZl1zPDVaaeEHItd+Yg="],
esn: "ABCDEF01",
macAddressType: ["wifi"],
fragment: 0,
userSerialNumber: 0,
};
const message = CheckinRequestModel.create(payload);
return CheckinRequestModel.encode(message).finish();
};
exports.buildCheckinRequest = buildCheckinRequest;
const parseCheckinResponse = async (data) => {
const root = await (0, protobufjs_1.load)(path.join(__dirname, "./proto/checkin.proto"));
const CheckinResponseModel = root.lookupType("CheckinResponse");
const message = CheckinResponseModel.decode(data);
const object = CheckinResponseModel.toObject(message, {
longs: String,
enums: String,
bytes: String,
});
return object;
};
exports.parseCheckinResponse = parseCheckinResponse;
const sleep = async (ms) => {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
};
exports.sleep = sleep;
function convertTimestampMs(timestamp) {
if (timestamp.toString().length === 10) {
return timestamp * 1000;
}
return timestamp;
}
//# sourceMappingURL=utils.js.map

1
build/push/utils.js.map Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/push/utils.ts"],"names":[],"mappings":"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"}