api: import updated version from the ios repo.
Improves types and adds functionality to getting crypto managers.master
parent
53930292ee
commit
f5df8cb4e1
|
@ -3,6 +3,9 @@ import { USER, PASSWORD, keyBase64 } from './TestConstants';
|
|||
|
||||
import { stringToByteArray } from './Helpers';
|
||||
|
||||
import * as sjcl from 'sjcl';
|
||||
sjcl.random.addEntropy('seedForTheTests', 1024, 'FakeSeed');
|
||||
|
||||
it('Derive key', () => {
|
||||
const derived = deriveKey(USER, PASSWORD);
|
||||
expect(derived).toBe(keyBase64);
|
||||
|
|
|
@ -6,6 +6,9 @@ const testApiBase = 'http://localhost:8000';
|
|||
|
||||
import { USER, PASSWORD, keyBase64 } from './TestConstants';
|
||||
|
||||
sjcl.random.addEntropy('seedForTheTests', 1024, 'FakeSeed');
|
||||
|
||||
|
||||
let credentials: EteSync.Credentials;
|
||||
|
||||
beforeEach(async () => {
|
||||
|
|
|
@ -4,7 +4,7 @@ import URI from 'urijs';
|
|||
import * as Constants from './Constants';
|
||||
|
||||
import { byte, base64, stringToByteArray } from './Helpers';
|
||||
import { CryptoManager, AsymmetricKeyPair, HMAC_SIZE_BYTES } from './Crypto';
|
||||
import { CryptoManager, AsymmetricCryptoManager, AsymmetricKeyPair, HMAC_SIZE_BYTES } from './Crypto';
|
||||
export { CryptoManager, AsymmetricCryptoManager, AsymmetricKeyPair, deriveKey, genUid } from './Crypto';
|
||||
|
||||
type URI = typeof URI;
|
||||
|
@ -83,7 +83,7 @@ class BaseItem<T extends BaseItemJson> {
|
|||
protected _content?: object;
|
||||
|
||||
constructor() {
|
||||
this._json = {} as any;
|
||||
this._json = {} as T;
|
||||
}
|
||||
|
||||
public deserialize(json: T) {
|
||||
|
@ -131,9 +131,13 @@ export interface JournalJson extends BaseJson {
|
|||
}
|
||||
|
||||
export class Journal extends BaseJournal<JournalJson> {
|
||||
constructor(version: number = Constants.CURRENT_VERSION) {
|
||||
constructor(initial?: Partial<JournalJson>, version: number = Constants.CURRENT_VERSION) {
|
||||
super();
|
||||
this._json.version = version;
|
||||
this._json = {
|
||||
...this._json,
|
||||
version,
|
||||
...initial,
|
||||
};
|
||||
}
|
||||
|
||||
get key(): byte[] | undefined {
|
||||
|
@ -152,6 +156,16 @@ export class Journal extends BaseJournal<JournalJson> {
|
|||
return this._json.version;
|
||||
}
|
||||
|
||||
public getCryptoManager(derived: string, keyPair: AsymmetricKeyPair) {
|
||||
if (this.key) {
|
||||
const asymmetricCryptoManager = new AsymmetricCryptoManager(keyPair);
|
||||
const derivedJournalKey = asymmetricCryptoManager.decryptBytes(this.key);
|
||||
return CryptoManager.fromDerivedKey(derivedJournalKey, this.version);
|
||||
} else {
|
||||
return new CryptoManager(derived, this.uid, this.version);
|
||||
}
|
||||
}
|
||||
|
||||
public setInfo(cryptoManager: CryptoManager, info: CollectionInfo) {
|
||||
this._json.uid = info.uid;
|
||||
this._content = info;
|
||||
|
@ -270,6 +284,10 @@ export class UserInfo extends BaseItem<UserInfoJson> {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public getCryptoManager(derived: string) {
|
||||
return new CryptoManager(derived, 'userInfo', this.version);
|
||||
}
|
||||
|
||||
public setKeyPair(cryptoManager: CryptoManager, keyPair: AsymmetricKeyPair) {
|
||||
this._json.pubkey = sjcl.codec.base64.fromBits(sjcl.codec.bytes.toBits(keyPair.publicKey));
|
||||
this._content = keyPair.privateKey;
|
||||
|
@ -323,14 +341,16 @@ class BaseNetwork {
|
|||
this.apiBase = URI(apiBase).normalize();
|
||||
}
|
||||
|
||||
// FIXME: Get the correct type for extra
|
||||
public newCall(segments: string[] = [], extra: any = {}, _apiBase: URI = this.apiBase): Promise<any> {
|
||||
public newCall<T = any>(segments: string[] = [], extra: RequestInit = {}, _apiBase: URI = this.apiBase): Promise<T> {
|
||||
const apiBase = BaseNetwork.urlExtend(_apiBase, segments);
|
||||
|
||||
extra = Object.assign({}, extra);
|
||||
extra.headers = Object.assign(
|
||||
{ Accept: 'application/json' },
|
||||
extra.headers);
|
||||
extra = {
|
||||
...extra,
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
...extra.headers,
|
||||
},
|
||||
};
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
fetch(apiBase.toString(), extra).then((response) => {
|
||||
|
@ -382,7 +402,7 @@ export class Authenticator extends BaseNetwork {
|
|||
body: form,
|
||||
};
|
||||
|
||||
this.newCall([], extra).then((json: {token: string}) => {
|
||||
this.newCall<{token: string}>([], extra).then((json) => {
|
||||
resolve(json.token);
|
||||
}).catch((error: Error) => {
|
||||
reject(error);
|
||||
|
@ -400,15 +420,15 @@ export class BaseManager extends BaseNetwork {
|
|||
this.apiBase = BaseNetwork.urlExtend(this.apiBase, ['api', 'v1'].concat(segments));
|
||||
}
|
||||
|
||||
// FIXME: Get the correct type for extra
|
||||
public newCall(segments: string[] = [], extra: any = {}, apiBase: any = this.apiBase): Promise<any> {
|
||||
extra = Object.assign({}, extra);
|
||||
extra.headers = Object.assign(
|
||||
{
|
||||
public newCall<T = any>(segments: string[] = [], extra: RequestInit = {}, apiBase: any = this.apiBase): Promise<T> {
|
||||
extra = {
|
||||
...extra,
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=UTF-8',
|
||||
'Authorization': 'Token ' + this.credentials.authToken,
|
||||
...extra.headers,
|
||||
},
|
||||
extra.headers);
|
||||
};
|
||||
|
||||
return super.newCall(segments, extra, apiBase);
|
||||
}
|
||||
|
@ -421,8 +441,8 @@ export class JournalManager extends BaseManager {
|
|||
|
||||
public fetch(journalUid: string): Promise<Journal> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.newCall([journalUid, '']).then((json: JournalJson) => {
|
||||
const journal = new Journal(json.version);
|
||||
this.newCall<JournalJson>([journalUid, '']).then((json) => {
|
||||
const journal = new Journal({ uid: json.uid }, json.version);
|
||||
journal.deserialize(json);
|
||||
resolve(journal);
|
||||
}).catch((error: Error) => {
|
||||
|
@ -433,9 +453,9 @@ export class JournalManager extends BaseManager {
|
|||
|
||||
public list(): Promise<Journal[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.newCall().then((json: JournalJson[]) => {
|
||||
this.newCall<JournalJson[]>().then((json) => {
|
||||
resolve(json.map((val: JournalJson) => {
|
||||
const journal = new Journal(val.version);
|
||||
const journal = new Journal({ uid: val.uid }, val.version);
|
||||
journal.deserialize(val);
|
||||
return journal;
|
||||
}));
|
||||
|
@ -451,7 +471,7 @@ export class JournalManager extends BaseManager {
|
|||
body: JSON.stringify(journal.serialize()),
|
||||
};
|
||||
|
||||
return this.newCall([], extra);
|
||||
return this.newCall<Journal>([], extra);
|
||||
}
|
||||
|
||||
public update(journal: Journal): Promise<{}> {
|
||||
|
@ -460,7 +480,7 @@ export class JournalManager extends BaseManager {
|
|||
body: JSON.stringify(journal.serialize()),
|
||||
};
|
||||
|
||||
return this.newCall([journal.uid, ''], extra);
|
||||
return this.newCall<Journal>([journal.uid, ''], extra);
|
||||
}
|
||||
|
||||
public delete(journal: Journal): Promise<{}> {
|
||||
|
@ -485,8 +505,8 @@ export class EntryManager extends BaseManager {
|
|||
});
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.newCall(undefined, undefined, apiBase).then((json: Array<{}>) => {
|
||||
resolve(json.map((val: any) => {
|
||||
this.newCall<EntryJson[]>(undefined, undefined, apiBase).then((json) => {
|
||||
resolve(json.map((val) => {
|
||||
const entry = new Entry();
|
||||
entry.deserialize(val);
|
||||
return entry;
|
||||
|
@ -524,8 +544,8 @@ export class JournalMembersManager extends BaseManager {
|
|||
|
||||
public list(): Promise<JournalMemberJson[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.newCall().then((json: JournalMemberJson[]) => {
|
||||
resolve(json.map((val: JournalMemberJson) => {
|
||||
this.newCall<JournalMemberJson[]>().then((json) => {
|
||||
resolve(json.map((val) => {
|
||||
return val;
|
||||
}));
|
||||
}).catch((error: Error) => {
|
||||
|
@ -559,7 +579,7 @@ export class UserInfoManager extends BaseManager {
|
|||
|
||||
public fetch(owner: string): Promise<UserInfo> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.newCall([owner, '']).then((json: UserInfoJson) => {
|
||||
this.newCall<UserInfoJson>([owner, '']).then((json) => {
|
||||
const userInfo = new UserInfo(owner, json.version);
|
||||
userInfo.deserialize(json);
|
||||
resolve(userInfo);
|
||||
|
|
|
@ -56,7 +56,7 @@ const journalsDeserialize = (state: {}) => {
|
|||
const newState = new Map<string, EteSync.Journal>();
|
||||
Object.keys(state).forEach((uid) => {
|
||||
const x = state[uid];
|
||||
const ret = new EteSync.Journal(x.version);
|
||||
const ret = new EteSync.Journal(uid, x.version);
|
||||
ret.deserialize(x);
|
||||
newState.set(uid, ret);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue